每次我的反应组件处理使用 useEffect 设置的事件挂钩时,如何防止 useState 变量被重置?

时间:2021-06-20 16:15:23

标签: javascript reactjs use-effect use-state

我想要一个反应组件来处理键盘输入。我在下面附上了我的组件的简化版本(显示了我遇到的问题)。

问题是:状态变量 inputText 没有更新。每次我按下一个键时,它似乎都会被设置回初始值 ""。我的假设是每次按下一个键时我的组件都会重新渲染。但为什么?

当使用“传统”input 元素时,这种方法非常有效。我发现了许多示例,其中 value 元素的 input 设置为状态变量,当用户将文本输入到 input 元素(以及 onChange事件触发)。

我做错了什么?

import './TestInput.css'
const { useState, useEffect } = require('react');

const TestInput = ( props ) => {
  const [ inputText, setInputText ] = useState("");

  useEffect(() => {
    window.addEventListener('keypress', handleKeyPress);
    console.log('Event listener added')
    return () => {
      window.removeEventListener('keypress', handleKeyPress);
      console.log('Event listener removed');
    }
  }, []);

  function handleKeyPress(e) {
    setInputText(inputText + e.key);
  }

  return (
    <div id="container">
      <div id="input"></div>
    </div>
  )
}

export default TestInput;

1 个答案:

答案 0 :(得分:1)

因为您将 useEffect 与空数组依赖项一起使用,所以 window.addEventListener 仅在第一次渲染中使用 handleKeyPress 调用一次。在此函数中,您直接使用状态 inputText,它的值仍然是初始值 '',并且在调用事件 keypress 时不会更新到新状态。

最简单的修复方法是不直接使用状态 inputText 并将函数传递给 setInputText

function handleKeyPress(e) {
  setInputText(preState => preState + e.key);
}