如何在 EventHandler 中使用状态变量 (useState)
How to use State Variable (useState) in an EventHandler
我有一个 React 功能组件,它从 useState() 接收一个带有变量的道具。这工作正常,但如果我在 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>;
};
我有一个 React 功能组件,它从 useState() 接收一个带有变量的道具。这工作正常,但如果我在 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>;
};