Reactjs 组件在异步反应上下文更新时呈现两次

Reactjs 组件在异步反应上下文更新时呈现两次,reactjs,react-hooks,react-context,react-state-management,react-state,Reactjs,React Hooks,React Context,React State Management,React State,我有一个React应用程序,它使用React上下文管理状态。我创造了简单 有两种情况。一个用于存储状态,另一个用于调度。这是一个从这个模式 状态上下文仅存储单个数字,并且在此状态下只能调用一个操作: function reducer(state: State, action: Action): State { switch (action.type) { case "inc": { return state + 1; } } } 我还有两个用于同步和异步递增

我有一个React应用程序,它使用React上下文管理状态。我创造了简单

有两种情况。一个用于存储状态,另一个用于调度。这是一个从这个模式

状态上下文仅存储单个数字,并且在此状态下只能调用一个操作:

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "inc": {
      return state + 1;
    }
  }
}
我还有两个用于同步和异步递增值的助手函数:

async function asyncInc(dispatch: React.Dispatch<Action>) {
  await delay(1000);
  dispatch({ type: "inc" });
  dispatch({ type: "inc" });
}

function syncInc(dispatch: React.Dispatch<Action>) {
  dispatch({ type: "inc" });
  dispatch({ type: "inc" });
}

异步函数asyncInc(dispatch:React.dispatch,通过采取一系列操作解决此问题,但我想知道是否可以避免此问题。

除非这会导致性能问题,否则我建议不要担心其他渲染。我发现在这个主题上很有帮助

但是,React看起来确实有一个不稳定的(因此不应该使用)API来批处理更新
ReactDOM。不稳定的批处理更新
。但是,如果它被删除或更改,使用它可能会在将来引起头痛。但是要回答您的问题“我们能以某种方式批处理更新吗?”,是的


基本上,您看到的
syncInc()
是单击事件。因此,您只能看到它渲染一次

React在React事件处理程序中批处理所有
设置状态
,并在退出自己的浏览器事件处理程序之前应用它们

对于您的
asyncInc()
,它不在事件处理程序的范围内(由于
async
),因此预计您将获得两次重新呈现(即不进行批处理状态更新)

我们可以批量更新吗


是的,可以在异步函数中进行响应。

谢谢!事实上,我刚刚更改了分派方法,在一个操作中执行一系列操作,而不是处理不稳定的API。这正是我期望在这里发生的事情,但我不知道有一些实验性的API可以处理它。感谢本文!
const counter = useCounterState();
const dispatch = useCounterDispatch();

return (
  <React.Fragment>
    <button onClick={() => asyncInc(dispatch)}>async increment</button>
    <button onClick={() => syncInc(dispatch)}>sync increment</button>
    <div>{counter}</div>
  </React.Fragment>
);
const asyncInc = async () => {
  await delay(1000);

  ReactDOM.unstable_batchedUpdates(() => {
    setCounter(counter + 1);
    setCounter(counter + 1);
  });
};