javascript - 反应 useCallback 钩子,没有收到更新的依赖状态值
问题描述
下面是我试图解决的问题的简化版本。
任何人都知道为什么我的handleKeydown
方法没有收到更新的activeTab
状态变量?我认为因为我添加activeTab
为依赖项,所以回调总是会收到更新的值。然而,情况似乎并非如此。
正如预期的那样,每次按下一个键时都会调用回调;但是,activeTab
始终null
是初始值。任何帮助表示赞赏!
(我已经包含了一个代码片段和一个 jsfiddle 链接(因为该片段似乎由于某种原因没有呈现。jsfiddle 至少呈现了大声笑)。)
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>
解决方案
该handleKeydown
函数在每次更改时更新activeTab
。但是,仅在挂载时调用useEffect
将函数绑定到事件的方法。keydown
因此,虽然函数被重新创建,但初始值为 的原始实例activeTab
被事件处理程序调用。
这里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>
推荐阅读
- powershell - 将 Sharepoint List A 内容与 Sharepoint List B 进行比较,并将差异写入 List B
- ios - 如何对一组复杂的 GKEntity 中的所有元素进行排序?
- python - 我无法在 tkinter Python 中更改按钮图像
- javascript - Javascript:DOM将元素移动到垂直中间
- html - 引导网格的图像超链接问题
- javascript - 如何查找和解决谷歌应用脚本中的“异常”错误?
- string - unsafe.SizeOf() 说任何字符串都需要 16 个字节,但是如何呢?
- android - Android Navigation Drawer 甚至没有调用公共布尔 onNavigationItemSelected 方法
- android - 在“制作应用程序类”步骤中使用 firebase_messaging 包时出现问题
- python-3.x - SublimeREPL 给出语法错误