i具有一个反应功能组件,该组件将带有usestate((变量的prop。这可以正常工作,但是如果我在EventListener中使用它,则不会更新。我尝试了以下内容,但仍然不起作用。
也许有人可以解释原因。
谢谢
我希望X是更新的数字,但它始终具有EventHandler的初始设置的值。
import React, { useState, useEffect } from "react";
import ReactDom from "react-dom";
const App = () => {
const [num, setNum] = useState(50);
return (
<div>
<button onClick={() => setNum(prev => prev + 1)}>Test</button>
<div>{num}</div>
<Child num={num} />
</div>
);
};
const Child = ({ num }) => {
let x = 0;
const md = () => {
console.log(num, x);
};
useEffect(() => {
x = num;
}, [num]);
useEffect(() => {
document.getElementById("box").addEventListener("mousedown", md);
return () => {
document.removeEventListener("mousedown", md);
};
}, []);
return <div id="box">click {num}</div>;
};
ReactDom.render(<App />, document.getElementById("app"));
Child
的每个渲染将获得新的 x
,一个新的 props
对象等。但是,您只绑定了一次侦听器一次,因此仅捕获初始的props.num
值。
修复的两种方法:
重生事件侦听器当num
更改时,通过传递num
作为对您的效果的依赖性来绑定事件侦听器的效果:
const Child = ({ num }) => {
useEffect(() => {
// no need to define this in main function since it is only
// used inside this effect
const md = () => { console.log(num); };
document.getElementById("box").addEventListener("mousedown", md);
return () => {
document.removeEventListener("mousedown", md);
};
}, [num]);
return <div id="box">click {num}</div>;
};
或使用ref
保持NUM的值并将事件侦听器绑定到Ref。这为您提供了一定程度的间接来处理更改:
const Child = ({ num }) => {
const numRef = useRef(); // will be same object each render
numRef.current = num; // assign new num value each render
useEffect(() => {
// no need to define this in main function since it is only
// used inside this effect
// binds to same ref object, and reaches in to get current num value
const md = () => { console.log(numRef.current); };
document.getElementById("box").addEventListener("mousedown", md);
return () => {
document.removeEventListener("mousedown", md);
};
}, []);
return <div id="box">click {num}</div>;
};