gpt4 book ai didi

reactjs - 组件在异步 React 上下文更新时渲染两次

转载 作者:行者123 更新时间:2023-12-03 14:11:19 25 4
gpt4 key购买 nike

我有 React 应用程序,它使用 React 上下文管理状态。我创建了简单的 counter incrementation reproduction .

有两个上下文。一个用于存储状态,第二个用于调度。这是取自此 article 的模式.

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

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" });
}

以下是在组件中使用它的方法:

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>
);

现在,当我单击同步增量按钮时,一切都会按预期工作。它将调用 inc 操作两次,将计数器递增 2,并且仅执行组件的一次重新渲染。

当我单击异步增量按钮时,它首先会等待一秒钟,然后执行inc操作两次,但它会重新渲染组件两次。

您必须打开控制台才能查看渲染组件的日志。

我有点明白这是为什么了。当它是同步操作时,一切都发生在组件渲染期间,因此它将首先操作状态并在最后渲染。当它是异步操作时,它会首先渲染组件,一秒后它会更新一次触发重新渲染的状态,并会第二次更新触发下一次重新渲染。

那么是否可以执行异步状态更新,只进行一次重新渲染?在同一个复制品中,有类似的示例,但使用 React.useState 也有同样的问题。

我们可以以某种方式批量更新吗?或者我必须创建另一个操作来同时对状态执行多个操作?

我还创建了 this reproduction通过采取一系列行动解决了这个问题,但我很好奇是否可以避免。

最佳答案

基本上,您所看到的 syncInc()batching对于点击事件。因此,您只能看到它渲染一次。

React batches all setStates done during a React event handler, and applies them just before exiting its own browser event handler.

对于您的asyncInc(),它超出了事件处理程序的范围(由于async),因此预计您会得到两次重新渲染(即不会不批量状态更新)。

Can, we somehow batch updates?

是的,React 可以 batch updates在异步函数内。

关于reactjs - 组件在异步 React 上下文更新时渲染两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58228163/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com