【发布时间】:2019-08-17 01:09:21
【问题描述】:
在 React Hooks 文档中,展示了如何在组件的清理阶段移除事件监听器。 https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect
在我的用例中,我正在尝试根据功能组件的状态属性删除EventListener。
这是一个永远不会卸载组件但应该删除事件侦听器的示例:
function App () {
const [collapsed, setCollapsed] = React.useState(true);
React.useEffect(
() => {
if (collapsed) {
window.removeEventListener('keyup', handleKeyUp); // Not the same "handleKeyUp" :(
} else {
window.addEventListener('keyup', handleKeyUp);
}
},
[collapsed]
);
function handleKeyUp(event) {
console.log(event.key);
switch (event.key) {
case 'Escape':
setCollapsed(true);
break;
}
}
return collapsed ? (
<a href="javascript:;" onClick={()=>setCollapsed(false)}>Search</a>
) : (
<span>
<input placeholder="Search" autoFocus />
<a href="javascript:;">This</a>
<a href="javascript:;">That</a>
<input placeholder="Refinement" />
</span>
);
}
ReactDOM.render(<App />, document.body.appendChild(document.createElement('div')));
(https://codepen.io/caqu/pen/xBeBMN 的实时示例)
我看到的问题是removeEventListener 中的handleKeyUp 引用在每次组件呈现时都会发生变化。函数handleKeyUp 需要引用setCollapsed,所以它必须被App 括起来。将handleKeyUp 移动到useEffect 内部似乎也会多次触发并丢失对原始handleKeyUp 的引用。
如何在不卸载组件的情况下使用 React Hooks 有条件地 window.removeEventListener?
【问题讨论】:
标签: reactjs react-hooks removeeventlistener