我有一个React函数组件与遗留的JQuery应用程序一起运行。在JQuery元素上调用事件处理程序时,传入的当前React状态默认为初始状态值,而不是更新后的状态值。
已验证的x状态通过useEffect挂钩进行更改,但在调用事件侦听器时,x被设置为初始状态值,而不是更新后的状态值。
function MyComponent(props) {
const [x, setX] = useState(false);
// On initial render
useEffect(() => {
props.jQueryButton.addEventListener('click', onXSave)
}, [])
useEffect(() => {
console.log("x changed " + x); // everytime onXChange is called, x
state is updated with the checked value, and this console.log shows
the correct state value
}, [x]);
onXChange = event => {
setX(event.target.checked); // checked is true in this context
};
onXSave = event => {
const obj = { x: x}; // x is false here, even though the state in this context shows it to be true.
};
}
不会显示任何错误消息。在上面的代码中,我希望onXSave方法调用中的x状态为true,但它一直显示为false。
要添加到eventListener
的onXSave
版本已过期-您在第一次渲染时只添加一次,因此当x
更新并导致重新渲染时,useEffect不会再次运行,jQueryButton
仍将保留原始函数,该函数已因x
的过期版本而关闭。
你需要做两件事:
- 将
onXSave
和jQueryButton
添加为useEffect
依赖数组中的依赖项(因此,当它重新渲染时,函数的当前版本将连接到eventListener( - 通过从
useEffect
返回一个清理函数,在重新渲染时删除旧的事件侦听器
所以类似于:
function MyComponent(props) {
const [x, setX] = useState(false);
// On initial render
useEffect(() => {
props.jQueryButton.addEventListener('click', onXSave)
return ()=> props.jQueryButton.removeEventListener('click', onXSave)
}, [onXSave, props.jQueryButton])
useEffect(() => {
console.log("x changed " + x); // everytime onXChange is called, x
state is updated with the checked value, and this console.log shows
the correct state value
}, [x]);
onXChange = event => {
setX(event.target.checked); // checked is true in this context
};
onXSave = event => {
const obj = { x: x}; // x is false here, even though the state in this context shows it to be true.
};
}
onXSave
被添加为初始渲染的处理程序,因此x
具有当时的值。在每次渲染中重新创建onXSave
并不重要,因为它从未在初始渲染后使用过。
要解决此问题,您可以将x
放入ref
unction MyComponent(props) {
const [x, setX] = useState(false);
const ref = useRef();
ref.current = x;
// On initial render
useEffect(() => {
props.jQueryButton.addEventListener('click', onXSave)
}, [])
useEffect(() => {
console.log("x changed " + x); // everytime onXChange is called, x
state is updated with the checked value, and this console.log shows
the correct state value
}, [x]);
onXChange = event => {
setX(event.target.checked); // checked is true in this context
};
onXSave = event => {
const obj = { x: ref.current}; // by using ref, the value is always current
};
}