ReactJS 并发 SetState 竞争条件 [英] ReactJS concurrent SetState race condition

查看:50
本文介绍了ReactJS 并发 SetState 竞争条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的组件结构

I have a component structure like this

<A>
    <B>
        <C/>
        <C/>
    </B>
    <D>
       <E/>
       <E/>
    </D>
</A>

想法是在块 E 中的组件上的操作由组件 A 的函数处理到 A 的状态,然后作为道具传递给 B 和 C.我知道,更好的方法是使用 Flux、pubsub-js 或其他 Store-message 系统,但希望有人能解释为什么我理解的最正确的解决方案不起作用.

Idea is that actions on components in block E are processed by a function of component A to state of A and than passed down to B and C as props. I know, that better way was to use Flux, pubsub-js or other Store-message system, but hope if someone can explain why correct to the best of my understanding solution doesn't work.

从组件 E 的多个实例同时调用组件 A 的这个函数会导致竞争条件,状态只有一个变化(而不是每个函数调用提供一个变化)

Calling this function of component A simalteneously from multiple instances of component E leads to race condition with only one change in state (instead of each function call providing a change)

updateState(value,index){
   this.setState(update(this.state, {
        a: {
          [index]: {
            b: {
             $set: value
            }
          }
        }
    })
);
}

这里的功能更新来自

import update from 'react/lib/update';

与 ReactJS 推荐做法背道而驰的糟糕解决方案,但效果很好:

Bad solution that goes against ReactJS reccomended practices, but works well:

updateState(value,index){
   this.state.a[index].b=value;
   this.forceUpdate();
);
}

我的问题是:

这是一个错误,多个同时 setState 调用了竞争条件,还是我在没有理解的情况下做错了什么?

Is it a bug, that multiple simalteneous setState invokes a race condition, or I'm doing something wrong without understnding it?

推荐答案

您可能希望将一个函数传递给 setState 以消除此类竞争条件.类似的东西:

You probably want to pass a function to setState which should remove such race conditions. Something like:

this.setState(currentState => {
  currentState.someProp++;
  return currentState;
});

即使应用程序的两个不同部分同时执行此操作,仍会调用这两个函数并且 someProp 将增加两次.

Even if two different parts of your application does this at the same time, both functions will still be called and someProp will be incremented twice.

如果你改为这样做:this.setState({someProp: this.state.someProp + 1}) 它只会增加一次,因为 this.state.someProp 不会在调用 setState 后直接更新.但是,当将函数传递给 setState 时,您将获得当前挂起状态作为参数,这使您可以选择像我的示例一样递增,或者将您的变更与发生的任何其他变更合并.

If you were to do this instead: this.setState({someProp: this.state.someProp + 1}) it would only be incremented once because this.state.someProp isn't updated directly after calling setState. But when passing a function to setState you get the current pending state as an argument, which gives you the option to either just increment like in my example, or merge your mutation with any other mutation that took place.

这篇关于ReactJS 并发 SetState 竞争条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆