[英]React useCallback hook, not receiving updated dependency state value
Below is my simplified version of the problem I'm trying to solve.下面是我试图解决的问题的简化版本。
Anyone know why my handleKeydown
method is not receiving the updated activeTab
state variable?任何人都知道为什么我的
handleKeydown
方法没有收到更新的activeTab
state 变量? I though that because I added activeTab
as a dependency, the callback would always receive the updated value.我认为因为我添加了
activeTab
作为依赖项,所以回调总是会收到更新的值。 However, that does not seem to be the case.然而,情况似乎并非如此。
The callback is called, as expected, every time a key is pressed;正如预期的那样,每次按下一个键时都会调用回调; However,
activeTab
is always null
, the initial value.但是,
activeTab
始终为null
,即初始值。 Any help is appreciated!任何帮助表示赞赏!
(I've included both a code snippet as well as a jsfiddle link (because the snippet does not seem to be rendering for some reason. The jsfiddle at least renders lol).) (我已经包含了一个代码片段和一个 jsfiddle 链接(因为该片段似乎由于某种原因没有呈现。jsfiddle 至少呈现了大声笑)。)
https://jsfiddle.net/Tom904/98veow5b/4/ https://jsfiddle.net/Tom904/98veow5b/4/
const Tabs = () => { const [activeTab, setActiveTab] = React.useState(null); const handleKeydown = React.useCallback(event => { console.log(activeTab); // if a user hits the escape key while a tab is active... if (event.key === 'Escape' && activeTab) { setActiveTab(null); } }, [activeTab]); React.useEffect(() => { window.addEventListener('keydown', handleKeydown); return () => { window.removeEventListener('keydown', handleKeydown); }; }, []); return ( <div> <button onClick={() => setActiveTab('1')}> 1 </button> <button onClick={() => setActiveTab('2')}> 2 </button> <button onClick={() => setActiveTab('3')}> 3 </button> <div> Active tab: {activeTab || 'None'} </div> </div> ) } ReactDOM.render( <Tabs/>, document.getElementById('root') );
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>
The handleKeydown
function is updated on every change of activeTab
.每次更改 activeTab 时都会更新
handleKeydown
activeTab
。 However the useEffect
in which you bind the function to the keydown
event is only called on mount.但是,将
useEffect
绑定到keydown
事件的 useEffect 仅在挂载时调用。 So although the function is recreated, the original instance, with the initial value of activeTab
, is called by the event handler.因此,尽管重新创建了 function,但初始值为
activeTab
的原始实例由事件处理程序调用。
The useCallback
here is redundant, and you can also use functional updates form of useState
to avoid the activeTab
dependancy:这里的
useCallback
是多余的,也可以使用useState
的功能更新形式来避免activeTab
依赖:
const Tabs = () => { const [activeTab, setActiveTab] = React.useState(null); React.useEffect(() => { const handleKeydown = event => { setActiveTab(activeTab => event.key === 'Escape' && activeTab? null: activeTab); }; window.addEventListener('keydown', handleKeydown); return () => { window.removeEventListener('keydown', handleKeydown); }; }, []); return ( <div> <button onClick={() => setActiveTab('1')}> 1 </button> <button onClick={() => setActiveTab('2')}> 2 </button> <button onClick={() => setActiveTab('3')}> 3 </button> <div> Active tab: {activeTab || 'None'} </div> </div> ) } ReactDOM.render( <Tabs/>, document.getElementById('root') );
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.