javascript - 使用 useEffect() 钩子(Hook)处理关键事件的正确方法是什么,另一方面触发本地状态更改?

标签 javascript reactjs react-hooks event-handling

对 React Hooks 相当陌生,我遇到了这个问题。我有一个功能组件,当我按下回车键(键码= 13)时,它接受输入并将其发送到父组件。该组件看起来像这样。

const SearchTermBar = (props) => {
const {resetStateSearchTerm, handlePowerToggleParent} = props;
const [inputTerm, handleInputChange] = useState('');
const inputRef = useRef();

useEffect(() => {
    const keyPressEvent = (e) => {
        if (e.keyCode === 13) {
            resetStateSearchTerm(inputTerm);
            handleInputChange('');
            handlePowerToggleParent('search');
        }
    };

    inputRef.current.addEventListener('keydown', keyPressEvent);
    let parentInputRef = inputRef;

    return () => {
        console.log('remove event listener');
        parentInputRef.current.removeEventListener('keydown', keyPressEvent);
    }
}, [inputTerm, resetStateSearchTerm, handlePowerToggleParent]);

return (
    <div className='SearchTermBar'>
        <input
            type='text'
            placeholder='Enter search term here (Press return to confirm)'
            className='SearchTermBar__Input'
            value={inputTerm}
            onChange={(e) => handleInputChange(e.target.value)}
            ref={inputRef}
        />
    </div>
);

问题在于,每次 inputTermprops 值发生变化时,都会注册和取消注册该事件。但我无法找出处理事件注册/删除的正确方法(理想情况下应该发生一次)我理解这是因为对 inputTerm 的依赖,但我想知道更好地解决这个问题。

最佳答案

您已经有了输入引用,您实际上不需要状态:

const NOP = () => {};
const DEFAULT_INPUT = "";

function SearchTermBar(props) {
  const { resetStateSearchTerm = NOP, handlePowerToggleParent = NOP } = props;
  const inputRef = useRef();

  useEffect(() => {
    const keyPressEvent = (e) => {
      if (e.keyCode === 13) {
        resetStateSearchTerm(inputRef.current.value);
        inputRef.current.value = DEFAULT_INPUT;
        handlePowerToggleParent("search");
      }
    };

    inputRef.current.addEventListener("keydown", keyPressEvent);
    let parentInputRef = inputRef;

    return () => {
      console.log("remove event listener");
      parentInputRef.current.removeEventListener("keydown", keyPressEvent);
    };
  }, [resetStateSearchTerm, handlePowerToggleParent]);

  return (
    <input
      type="text"
      placeholder="Enter search term here (Press return to confirm)"
      style={{ width: "50%" }}
      ref={inputRef}
    />
  );
}

无论哪种方式,如果您想保留状态,则应将其值复制到引用中以修复 useEffect 中的闭包。可以通过添加另一个 useEffect 来完成,这将更新提到的引用。

Edit hardcore-gates-iyffi

关于javascript - 使用 useEffect() 钩子(Hook)处理关键事件的正确方法是什么,另一方面触发本地状态更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68525849/

相关文章:

javascript - 未生成 Webpack 捆绑文件

javascript - 如何显示/隐藏 ReactJS 组件

reactjs - 如何从 api 获取数据并将其作为原始数据显示在前端?

reactjs - react Hook linting : Does it always make sense?

javascript - ReactJS - UseRef,而不是 useState,来替换 props

防止机器人提交表单的 JavaScript 代码

javascript - 外部 Javascript 中 JQuery 调用的范围问题?

javascript - jQuery,将所有元素向下移动

javascript - 由于 bootstrap css,响应表无法正确折叠

reactjs - 我想在 react 表列的单元格内创建一个按钮