useState Hook 在事件监听器中不起作用

useState Hook not working inside event listener

setter 使用 useState 的函数在事件侦听器函数中不工作。

问题陈述:使用“Down/Up”键可访问性制定搜索建议。

实施:

              <input
                  style={{ outline: "none" }}
                  placeholder="Search Here"
                  className="w-full text-gray-800"
                  onClick={() => {
                    setShowSuggestion(true);
                    document.addEventListener("keydown", escFunction, false);
                  }}
                  onChange={(event) => setTitle(event.target.value)}
                  value={value}
                />
              <div
                className={
                  !showSuggestion
                    ? "hidden"
                    : "flex flex-row border border-gray-300 border-t-0  mx-auto w-3/4 space-x-4"
                }
              >
                <ul className="w-full">
                  {people.map((person) => (
                    <li
                      key={person.id}
                      className={cursor === person.id ? "bg-red-500" : ""}
                    >
                      {person.name}
                    </li>
                  ))}
                </ul>
              </div>

  function escFunction(event) {
    if (event.keyCode === 27) {
      document.removeEventListener("keydown", escFunction);
      setShowSuggestion(false);
    }

    if (event.keyCode === 40) {
      const nextId = cursor + 1;
      setCursor(nextId);   //---------------> this line not setting the value
      setTitle(people[nextId].name);
    }
  }

**问题:** 按键事件被触发,但是setter功能在第一次点击后不起作用

不应将事件侦听器添加到文档中,而应将其添加到输入键按下事件中。在访问其名称之前,还要检查人员对象的密钥是否可用 - people[nextId].name。这应该可以解决您的问题:

<input
                  style={{ outline: "none" }}
                  placeholder="Search Here"
                  className="w-full text-gray-800"
                  onClick={() => {
                    setShowSuggestion(true);
                  }}
                  onKeyDown={escFunction}
                  onChange={(event) => setTitle(event.target.value)}
                  value={value}
                />

cursor 的值(更新值)在执行 escFunction 期间不可用。 为了访问必须将其转换为 setCursor(currentId => currentId + 1);

的值
setCursor(currentId =>{

// do pre processing
return cursor+1
})

如评论中所暗示:

  • 传递回调允许您访问当前状态值。您的代码在上次渲染子项时围绕状态值创建一个闭包。

  • cursor从状态里面那个闭包函数一直是初始值,因为闭包函数