当您按下一个键时,此组件始终警报0:(run it online)
const Hello = () => {
const [counter, setCounter] = React.useState(0)
let canvas = React.useRef()
let add = () => {
setCounter(counter + 3)
alert(counter)
}
React.useEffect(() => {
window.onkeydown = add
}, [])
return <div><h1>{counter}</h1></div>
}
但是我的愿望输出是警告当前状态,而不是初始状态。
如果我将其更改为:
React.useEffect(() => {
window.onkeydown = add
})
工作正常(在每个渲染器上将add
事件处理程序绑定到onkeydown
。)
但是为什么它会这样呢? (我不想在每个渲染器上绑定事件处理程序,因为它似乎存在性能问题)
答案 0 :(得分:2)
仅在组件使用空的依赖项数组挂载时设置回调,从而将初始状态包含在附加的回调中。功能状态更新不会出现此问题,因为它使用回调函数来计算并从先前的状态值返回新的状态值。
更新的代码
const Hello = () => {
const [counter, setCounter] = React.useState(0);
let canvas = React.useRef();
const add = () => {
setCounter(counter => counter + 3);
};
React.useEffect(() => {
console.log(counter); // or alert, if you really want to
}, [counter]);
React.useEffect(() => {
window.addEventListener("keydown", add);
return () => window.removeEventListener("keydown", add);
}, []);
return (
<div>
<h1>{counter}</h1>
</div>
);
};
答案 1 :(得分:0)
传递空数组只会在安装组件时触发useEffect
,只需在数组中添加计数器,以便每次状态更新时都触发它。
React.useEffect(() => {
window.onkeydown = add
}, [counter])