当前位置: 首页 > 知识库问答 >
问题:

在useState挂钩中设置状态后,React状态变量不准确

冀弘厚
2023-03-14

我有一个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。

共有2个答案

龚星洲
2023-03-14

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
  };
}
郦昆
2023-03-14

您正在添加到eventListeneronXSave版本已过期-您只在第一次渲染时添加一次,因此当x更新并导致重新渲染时,useEffect不会再次运行,而jQueryButton仍将保留原始功能,已在过期版本的x上关闭。

你需要做两件事:

  1. 添加onXSave和您的jQueryButton作为依赖项在您的use效应依赖数组中(因此,当它重新呈现时,您的函数的当前版本挂接到您的eventListener)
  2. 通过从你的use效应中返回一个清理函数来删除重新呈现中的旧事件侦听器。

比如:

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.
  };


}
 类似资料:
  • 我想用React useState钩子设置多个状态值,这样我就可以用useEffect钩子分别更新它们。我有以下代码: 但是当我用React DevTools检查应用程序时,我会看到钩子的多个“状态”值,而不是“订单”、“支付”、“提交”等。

  • 我有一个小的井字游戏,一切都很好,除了我正在努力寻找在代码中放置完成功能的位置。让我给你看; 这基本上是整个游戏,我在另一个文件中有一个整理函数,就像这样; 完成功能也可以正常工作,但是由于useState是异步工作的,我知道这一点,我正在努力把它放在哪里。如果我把点击功能放在里面,它就不能对新的状态做出反应,只能对之前的状态做出反应。如果我把外面加上只是if语句,它会说渲染太多,因为我正在设置获

  • 我正在尝试使用状态将一个表单输入值复制到另一个表单输入值,但状态没有更新 我创建了一个带有按钮的表单,其中左侧表单输入的值应复制到右侧表单输入。这是我的代码: 无论我做什么,dbSecName的状态都不会改变。我试着设置一个新的常量。我尝试使onclick函数异步并等待。如果我为我试图设置的变量的值添加,我可以正确地看到它,但是dbSecName的console.log总是显示原始值。 我真的不知

  • 问题内容: 可以说我有一些状态依赖于其他状态(例如,当A更改时,我希望B更改)。 创建一个观察A并将B设置在useEffect钩内的钩子是否合适? 效果是否会级联,从而在我单击按钮时会触发下一个效果,从而导致b发生变化,从而导致第二个效果在下一次渲染之前触发?这样构造代码是否有性能下降? 问题答案: 效果始终在渲染阶段完成后执行,即使您将setState放在一个效果中,另一个效果也将读取更新后的状

  • 问题内容: 我正在尝试新的React Hooks,并有一个带有计数器的Clock组件,该计数器应该每秒增加一次。但是,该值不会增加到超过一。 问题答案: 原因是传递给的闭包中的回调仅访问第一个渲染器中的变量,而无法访问后续渲染器中的新值,因为第二次未调用。 回调中的值始终为0 。 就像您熟悉的状态挂钩一样,状态挂钩有两种形式:一种是处于更新状态的状态,另一种是将当前状态传入的回调形式。您应该使用第

  • 问题内容: 当我用酶测试类组件时,我可以设置状态。当我用钩子测试功能组件时,现在该怎么做? 例如,在我的组件中,我有: 我想在测试中进行更改 问题答案: 使用挂钩状态时,您的测试必须忽略诸如状态之类的实现细节,以便对其进行正确测试。您仍然可以确保组件将正确的状态传递到其子级。 您可以在Kent C. Dodds撰写的这篇博客文章中找到一个很好的例子。 这是摘录的代码示例。 依赖状态执行细节的测试-