【发布时间】:2019-11-18 11:37:23
【问题描述】:
我正在尝试使用 react-hooks 为列表实现键盘导航。
重要 - 此列表可以根据搜索缩小/增长。
我的问题在于应该运行一些回调的 Enter 键。
activeCursor 没有改变,我理解因为它不在 useEffect 数组中,但是我怎样才能在 handleKeyPress 中获取当前状态而无需重新运行 useEffect ?
另外,理想情况下,我希望只在挂载 ([]) 上运行我的 useEffect,但由于 filteredMessages 发生变化,我必须重新调用它,这也是我觉得奇怪的事情,因为它是 eventListeners 所以我什至不确定他们每次会发生什么......
const useKeyboardNavigation = (filteredMessages, onMessageSelection) => {
const [activeCursor, setActiveCursor] = React.useState(0);
const size = filteredMessages.length
const handleKeyPress = (event) => {
if (event.key === 'ArrowDown') {
setActiveCursor(prev => prev < size ? prev + 1 : 0)
}
else if (event.key === 'ArrowUp') {
setActiveCursor(prev => prev > 0 ? prev - 1 : size)
}
else if (event.key === 'Enter') {
const msg = filteredMessages[activeCursor] // ??? Always 0
onMessageSelection(msg)
}
};
React.useEffect(
() => {
// Each time the list changes I reset the cursor
setActiveCursor(0)
document.addEventListener('keydown', handleKeyPress);
return () => document.removeEventListener('keydown', handleKeyPress);
},
[filteredMessages]
);
return [activeCursor, setActiveCursor];
}
【问题讨论】:
-
鉴于
handleKeyPress依赖于filteredMessages和activeCursor,那么当它们发生变化时必须重新创建它,并且由于useEffect使用handleKeyPress那么它还需要重新运行 - 什么是问题? -
在课堂上,我可以通过调用
this.state来获取handleKeyPress中的状态。有了钩子,我现在每次光标移动时都必须重新添加 eventListener -
不一定,您可以使用
ref来跟踪当前光标。但是,当光标改变时是否需要取消挂钩/重新预订真的很重要吗?您遇到问题了吗? -
正如@James 提到的,您可以使用
ref获取当前状态(查看 Dan Abramov 的博客,A Complete Guide to Use Effect - Swimming against the tide)部分。我也有兴趣访问当前状态值。
标签: reactjs react-hooks use-effect