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

使用React Hook setSomeSetting更改组件状态落后一步

白博易
2023-03-14

我试图使用React Hooks来管理一个简单的文本输入字段和提交输入按钮的状态。输入字段不断验证(现在只是检查长度

我已将参数扩展为setMuffinSettings,以显式返回一个对象,并已确认此返回对象的顺序为:true。因此,问题与setMuffinSettings本身有关,而不是传递给setMuffinSettings的对象不正确。

我还研究了另外两个与React挂钩(特别是挂钩)和“落后一步”有关的StackOverflow问题。这两个问题的解决方案都不能解决我的问题。

React hook和settings变量初始化:

  const [muffinSettings, setMuffinSettings] = useState({
    isInStock: false,
    isOrdered: false,
  });

提交按钮事件处理程序

  const handleMuffinOrder = () => {
    console.log(muffinSettings); // BEFORE: isOrdered is correctly false
    if (muffinSettings.isInStock) {
      console.log('reached'); // this is printed so it's not an issue with isInStock
      setMuffinSettings(prev => ({ ...prev, isOrdered: true }));
    }
    console.log(muffinSettings); // AFTER: isOrdered is incorrectly still false
  }

提交按钮:

    return (
      <SubmitOrderButton>
        text="Submit your muffin order"
        // onButtonClick={handleMuffinOrder}
        onButtonClick={() => handleMuffinOrder()}
        // the 2 lines above give me the same error
      />
    );

我希望在setMuffinSettings调用之前,muffinSettings.isOrdered为FALSE,之后为TRUE,前提是muffinSettings.isInStock为TRUE(事实上是)。

用我现在的代码,muffinSettings落后了一步。在下面handleMuffinOrder的代码片段中,我包含了第一次单击按钮时打印的控制台输出。但是,第二次单击它时,isOrdered BEFORE的值已设置为TRUE。因此,isOrdered的值似乎在第一次和第二次按钮点击之间发生了变化。

我相信这不是建议的“setState不会立即更新状态”问题的重复,因为我们在这里使用了React钩子,它只是在React 16.8之后才可用,而不是“旧的”React状态系统。根据React文档,setMuffinSet接受的唯一参数是新状态,即新对象;它不会像上面建议的问题答案建议的那样进行回调。

共有3个答案

司浩壤
2023-03-14
 const [isInStock, setIsInState] = useState(true);
  const [isOrdered, setIsOrdered] = useState(false);

  const handleMuffinOrder = () => {
    if (isInStock) {
      setIsOrdered(true);
    }
  };
  console.log(isInStock, isOrdered);
  return <button onClick={() => handleMuffinOrder()}> Click Me </button>;
};

对于这样一个简单的组件,这是最简单的方法。我在CodeSandbox中进行了测试,它将的状态更改为true

曾沛
2023-03-14

即使在钩子中,setState的基本实现也保持不变。它仍然是异步的。

再次引用文档:

状态更新可能是异步的。您不应该依赖它们的值来计算下一个状态。

关正雅
2023-03-14

它本身并不落后一步,它比这更微妙——出于性能原因,状态更新是批处理的,并且异步发生。如果你需要在状态改变后做一些事情,那么use效应就是你的朋友。

 类似资料:
  • 问题内容: 我正在使用ReactJS构建一个非常原始的测验应用程序,但无法更新组件的状态。它的行为是,尽管在以下方面始终落后一步,但它仍为DOM提供了正确的数组索引: 问题答案: 是不必是同步操作: 不会立即变异,但会创建待处理的状态转换。向后进入 无法保证对呼叫的同步操作,并且可以为提高性能而对呼叫进行批量处理。 因此,此处可能仍保留先前的值: 相反,请 使用 状态转换完成后调用的回调函数:

  • 这个问题在这里已经得到了回答,但事情总是在变化。 基本上,父组件获取一些数据,子组件需要这些数据。 这是子组件。

  • 问题内容: 我正在尝试制作一个不错的ApiWrapper组件,以填充各种子组件中的数据。从我阅读的所有内容来看,这应该可以正常工作:https : //jsfiddle.net/vinniejames/m1mesp6z/1/ 但是由于某种原因,当父状态更改时,子组件似乎没有更新。 我在这里想念什么吗? 问题答案: 您的代码有两个问题。 您的子组件的初始状态是通过props设置的。 引用此SO答案:

  • 我正在尝试制作一个很好的ApiWrapper组件来填充各种子组件中的数据。从我读到的所有内容来看,这应该是可行的:https://jsfidle.net/vinniejames/m1mesp6z/1/ 但由于某种原因,当父状态更改时,子组件似乎没有更新。 我是不是漏了什么?

  • 我正在尝试使用React Redux。我遇到了这样一种情况:一个连接的组件(Coordinates.jsx)嵌套在另一个连接的组件(Canvas.jsx)中。 源代码https://github.com/RinatRezyapov/Vault-13.git(纱线安装,然后纱线开始) 在父组件画布中。jsx I在componentDidMount()中调度一个操作,该操作不可变地更改状态。 帆布js

  • 我有两个组件:父组件,我想改变子组件的状态: 和子组件: 我需要从父组件更改子组件的打开状态,或者当单击父组件中的按钮时,从父组件调用子组件的toggleMenu()?