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

时间:2021-05-16 10:45:57

标签: javascript reactjs react-hooks addeventlistener use-state

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

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

实施:

  • 创建一个搜索栏组件。
              <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>
  • 点击搜索栏添加事件列表以检查按键
  • 在 keyevent ==“向下箭头键”上,设置选定的推荐 = 列表中的下一项。

  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功能不起作用。

2 个答案:

答案 0 :(得分:0)

与其向文档添加事件侦听器,不如将其添加到输入 keydown 事件中。在访问其名称 - 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}
                />

答案 1 :(得分:0)

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

setCursor(currentId =>{

// do pre processing
return cursor+1
})

正如评论中所暗示的:

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

  • 来自该闭包函数内部状态的光标总是初始值,因为闭包函数