React UseEffect 与 window click eventListener 的奇怪行为
Weird behavior of React UseEffect with window click eventListener
我正在尝试实现一个简单的 window 点击计数器。它需要计算整个页面的点击次数,而不是像 <div onClick={() => handleClick()}></div>
.
这样的单个元素的点击次数
我已经尝试过此代码的多种变体:
import React, { useState, useEffect } from 'react';
import $ from 'jquery';
function Test() {
const [clicks, setClicks] = useState(0);
function handleClick() {
try {
setClicks(() => clicks + 1);
} catch (err) {
console.error(err);
}
}
useEffect(() => {
console.log(clicks);
}, [clicks]);
useEffect(() => {
$(window).on('click', handleClick);
return () => {
$(window).off('click', handleClick);
};
}, []);
return (<div>{clicks}</div>);
}
export default Test;
第一个 useEffect
只是在每次更改时记录 click
状态变量,因此我可以看到发生了什么。第二个添加事件侦听器并在组件卸载时将其删除。
问题是它在第一次点击时工作得很好。第一个 useEffect
记录 1
并且 <div>
中的值更改为 1
。但是,如果我继续点击,则不会发生任何其他事情。这种做法错了吗?
谢谢!
你有一个经典的 stale closure 问题。改用这个:
setClicks((clicks) => clicks+ 1);
按照您的方式,您的 clicks
将始终引用第一个渲染的值;它从未更新过,因为你 运行 你的 useEffect
只有一次。
我正在尝试实现一个简单的 window 点击计数器。它需要计算整个页面的点击次数,而不是像 <div onClick={() => handleClick()}></div>
.
我已经尝试过此代码的多种变体:
import React, { useState, useEffect } from 'react';
import $ from 'jquery';
function Test() {
const [clicks, setClicks] = useState(0);
function handleClick() {
try {
setClicks(() => clicks + 1);
} catch (err) {
console.error(err);
}
}
useEffect(() => {
console.log(clicks);
}, [clicks]);
useEffect(() => {
$(window).on('click', handleClick);
return () => {
$(window).off('click', handleClick);
};
}, []);
return (<div>{clicks}</div>);
}
export default Test;
第一个 useEffect
只是在每次更改时记录 click
状态变量,因此我可以看到发生了什么。第二个添加事件侦听器并在组件卸载时将其删除。
问题是它在第一次点击时工作得很好。第一个 useEffect
记录 1
并且 <div>
中的值更改为 1
。但是,如果我继续点击,则不会发生任何其他事情。这种做法错了吗?
谢谢!
你有一个经典的 stale closure 问题。改用这个:
setClicks((clicks) => clicks+ 1);
按照您的方式,您的 clicks
将始终引用第一个渲染的值;它从未更新过,因为你 运行 你的 useEffect
只有一次。