代码之家  ›  专栏  ›  技术社区  ›  J. Hesters

React中setState的这两种更新程序函数是否相等?

  •  2
  • J. Hesters  · 技术社区  · 7 年前

    我最近了解到 updater functions 对于 setState 在反应中。

    现在我看到这个概念用了两种不同的方式。假设我们有这样一个状态对象:

    interface State {
      readonly expanded: boolean;
      readonly slugs: string[];
    }
    
    state: State = { expanded: false, slugs: [] }
    

    this.setState(prevState => ({ ...prevState, expanded: !prevState.expanded }));
    

    就像这样:

    this.setState(({ expanded }) => ({ expanded: !expanded }));
    

    state (在这种情况下 slugs

    编辑: 此问题已标记为的副本 this question ,但它本质上是不同的,因为我想知道 而不是关于TypeScript的类型注释是如何工作的。为了清晰起见,我只提供了TypeScript类型。很抱歉,这个问题引起了混乱。英语不是我的主要语言,我不知道如何更清楚地表达这一点。幸运的是,有人完全理解并回答了这个问题。

    4 回复  |  直到 7 年前
        1
  •  8
  •   Sulthan    7 年前

    如果你研究源代码,特别是 setState enqueueSetState ,您可以看到以下代码:

    if (typeof partialState === 'function') {
      partialState = partialState.call(
        pu blicInstance,
        currentState,
        publicInstance.props,
      );
    }
    
    // Null and undefined are treated as no-ops.
    if (partialState === null || partialState === undefined) {
      return;
    }
    
    this._renderer._newState = {
      ...currentState,
      ...partialState,
    };
    

    这意味着

    this.setState(({ expanded }) => ({ expanded: !expanded }));
    

    state = {...prevState, {expanded: !expanded}}
    

    this.setState(prevState => ({ ...prevState, expanded: !prevState.expanded }));
    

     state = {...prevState, ...{...prevState, expanded: !prevState.expanded}}
    

    我认为第二个问题基本上是对updater函数如何工作的理解不足。

        2
  •  3
  •   kkdev163    7 年前
        3
  •  2
  •   letsc    7 年前

    这两条语句都会导致相同的行为-更新 expanded 价值 setState 方法的文档中,我们希望该方法返回需要重写的值。React将方法的返回合并到前一个状态对象,并进行区分。在第一个子句中,除了 扩大 扩大 是变异的。

        4
  •  1
  •   Bhojendra Rauniyar    7 年前

    要理解第二个代码,您可以查看附件 duplicate post ,但我发现你的情况有点不同。因此,在这里回答。

    this.setState(prevState => ({ ...prevState, expanded: !prevState.expanded }));
    

    ...prevState 只是没有必要。这是因为react的setState处理特定状态并合并其他状态。

    this.setState(prevState => ({ expanded: !prevState.expanded }));
    

    仅当需要更新嵌套在特定状态中的属性时,才需要使用合并。例如,如果您有以下内容:

    state = {
      people: {
       male: 1033,
       female: 234,
       other: 100
      }
    }
    

    现在,在这种情况下,您可以在只更新男性计数时合并人员值,如:

    this.setState(prevState => ({ people: { ...prevState.people, male: 1045 } }))
    

    this.setState(({people}) => ({ people: { ...people, male: 1045 } })