同一函数体中的 React 上下文更新被聚合为具有数据存储的单个事务,这是预期的行为吗?

React context updates in same function body are aggregated as a single transaction with data store, is this expected behavior?

虽然我最近使用 React Context 模式取得了成功,但我 运行 遇到了一个我想更好地理解的问题。

模式由下面 link 处的代码描述。本质上,我使用上下文 API 来创建一个单例 class。我喜欢这种模式,因为它保持不变性,但提供了一些不错的 OO 功能。

我 运行 遇到的问题是,如果在同一 ~member 函数中调用上下文 dispatch 更新,则它们不会单独传播。看起来它们正在聚合成一个 t运行saction。这对于某些场景中的性能非常有用。但是,这里不是那么多。

示例成员函数:

export const makeRunCapiProcess = (state : CapiContextI)=>(process : ()=>void)=>{ 
    

   
       const capiProcessName = Shortid.generate();

       state.dispatch({
        type: "def",
        payload: {
            ...state,
            core : {
                ...state.core,
                [capiProcessName] : process
            }
        }
    })

    process()

    // !!!!!!!!!!!!!!!!!!!
    // THIS IS THE PROBLEM AREA
    // !!!!!!!!!!!!!!!!!!!

    // Updates to context state are only propagated after this call.
    // Can circumvent this by wrapping in async or using setTimeout,
    // but that has resulted in a failure to set some proccesses to false.
    // I have also tried using a state.forceUpdate() here, but to no avail.
    state.dispatch({
        type: "def",
        payload: {
            ...state,
            core : {
                ...state.core,
                [capiProcessName] : false
            }
        }
    })

    return capiProcessName;


}

最小可重现示例: Check it out on CodeSandbox

如评论中所述,我可以通过 setTimeoutasync IIE 解决此问题,但这会导致其他问题。

我会注意到我正在使用 CRA default;我想知道这是否可能是一些聪明但不那么聪明的编译器技巧。

编辑 1: 正如现在在评论中指出的那样,我还尝试将 forceUpdate 成员添加到单例中。但是,这似乎是在两次调用之后调用的,因此没有解决我的问题。

编辑 2: 我仍然很好奇幕后发生的事情。但是,我认为这是一种过于迫切的模式。如果你发现这个 post 并且你正在寻找类似的东西,我认为通过提供某种状态变化然后触发提供者的 useEffect 中的清理来实现它通常会更好。

部分回答我自己的问题:

不要尝试 运行 在单个函数中更新多个上下文。它们是分批的。有关更多信息,请参阅 React GitHub 上的此线程:https://github.com/facebook/react/issues/21899