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

Javascript 使用React Hook setSomeSetting更改组件状态落后一步,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我试图使用React钩子来管理一个简单文本输入字段和提交输入按钮的状态。输入字段将持续验证(现在只是检查长度是否>=1),目标是在单击submit按钮且输入有效时,状态对象的'isOrdered'键的值为TRUE 我已将参数扩展为setMuffinSettings,以显式返回一个对象,并已确认此返回对象的顺序为:true。因此,问题与setMuffinSettings本身有关,而不是传递给setMuffinSettings的对象不正确 我还研究了另外两个与React挂钩(特别是挂钩)和“落后一步

我试图使用React钩子来管理一个简单文本输入字段和提交输入按钮的状态。输入字段将持续验证(现在只是检查长度是否>=1),目标是在单击submit按钮且输入有效时,状态对象的'isOrdered'键的值为TRUE

我已将参数扩展为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
      />
    );
返回(
text=“提交您的松饼订单”
//onButtonClick={handleMuffinOrder}
onButtonClick={()=>handleMuffinOrder()}
//上面的两行给了我同样的错误
/>
);
我希望在setMuffinSettings调用之前,muffinSettings.isOrdered为FALSE,之后为TRUE,前提是muffinSettings.isInStock为TRUE(事实上是)

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


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

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

再次引用:

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


这并不是落后一步,而是更微妙的——出于性能原因,状态更新是批处理的,并且是异步进行的。如果在状态更改后需要执行某些操作,则是您的朋友。

const[isInStock,setIsInState]=useState(true);
 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>;
};
const[isOrdered,setIsOrdered]=useState(false); 常量handleMuffinOrder=()=>{ 如果(isInStock){ 设置有序(真); } }; 控制台日志(isInStock,已排序); return handleMuffinOrder()}>单击我; };
对于这样一个简单的组件,这是最简单的方法。我在CodeSandbox中进行了测试,它将的状态更改为true

的可能副本