【问题标题】:Why function not passed as reference in the eventlistener in ReactJS为什么函数没有在 ReactJS 的事件监听器中作为引用传递
【发布时间】:2020-12-23 15:34:39
【问题描述】:

我在 ReactJS 中使用函数式组件。

const [showState, setState] = useState();

useEffect(() => {
  document.addEventListener('click', handleClick);
  return () => {
    document.removeEventListener('click', handleClick);
  }
}, []);

function handleClick(event) {
  console.log(showState);
};

function toggleState() {
  setState(true);
}
return ( <
  button onClick = {
    toggleState
  } > Toggle < /button>
)

当我通过按下按钮切换状态时,然后当我通过单击某处触发单击事件(handleClick 函数)时,控制台显示“未定义”。但是handleClick函数不是作为引用传递给click eventListener吗,当通过toggle切换状态时,它应该在控制台中显示“true”。

【问题讨论】:

  • 尝试通过将false 传递给您的addEventListener 来禁用useCapture
  • @bertdida 它不起作用

标签: javascript reactjs dom-events ref


【解决方案1】:

当您创建函数handleClick 时,它通过闭包捕获showState 的值,并且该值在第一次渲染时未定义。但是当你调用 toggleState 时,React 不会更改 showState 的值,而是使用新值重新渲染组件,并创建一个新的 handleClick 实例,并捕获新值。但是全局监听器仍然使用undefined 存储旧版本的函数。

您可以使用useRef 或将handleClick 包装到useCallback 并将其作为依赖项添加到useEffect 来实现所需的结果。

useRef 允许您在渲染之间保持引用:

const showState = useRef();

function handleClick(event) {
  console.log(showState.current);
};

function toggleState() {
  showState.current = true;
}

但是,您应该记住,useRef 不会触发重新渲染。

还有useCallback:

const [showState, setState] = useState();

const handleClick = useCallback(() => {
  console.log(showState);
}, [showState]);

useEffect(() => {
  document.addEventListener('click', handleClick);

  return () => {
    document.removeEventListener('click', handleClick);
  }
}, [handleClick]);

这样每次showState 更改创建的handleClick 的新实例,在闭包中使用新值,并且useEffect 被触发重新附加事件侦听器。

【讨论】:

猜你喜欢
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 2019-12-30
  • 2015-08-18
相关资源
最近更新 更多