【问题标题】:React + TypeScript - how to update state with single object with a "dynamic" set of changesReact + TypeScript - 如何使用“动态”更改集更新单个对象的状态
【发布时间】:2020-05-01 09:30:49
【问题描述】:

我想在条件更新列表的末尾更新状态并累积要立即提交的更改(以避免 setState 出现异步问题)。

interface IMyComponentState {
    a: string;
    b: string;
    c: string;
}

(...)

updateState = (condition1: boolean, condition2: boolean) => {
    const stateChanges: Partial<IMyComponentState> = {};

    if (condition1) {
        stateChanges.a = 'someValue 1';
    }
    if (condition2) {
        stateChanges.b = 'someValue 2';
    }
    this.setState(
        { ...this.state, ...stateChanges },
        () => this.doSomethingThatDependsOnState()
    );
}

这很好用,但有没有办法不使用this.state,如下所示?

    this.setState(
        {...stateChanges},
        (...)
    );

这里tslint 抱怨setState 需要Pick&lt;IMyComponentState, "a" | "b" | "c"&gt; 类型的对象,但这需要我提前指定(并预测)要更改的属性,这是不可能的。我听说 React 的 diffing 算法会检查引用,但我仍然担心将整个 state 对象放入 setState 会增加额外的开销或者是不必要的。

【问题讨论】:

    标签: reactjs typescript setstate tslint


    【解决方案1】:

    首先,您不需要传播this.state,React 只会将状态更改应用到指定的键。

    其次,setState 的类型故意不使用Partial&lt;T&gt;,这是因为在键上设置undefined显式会执行状态更新,所以它使用Pick (GitHub issue here talking more about it)

    要解决此问题,您可以将状态更新转换为 Pick&lt;IMyComponentState, keyof IMyComponentState&gt;

    updateState = (condition1: boolean, condition2: boolean) => {
      const stateChanges = {};
    
      if (condition1) {
        stateChanges.a = 'someValue 1';
      }
      if (condition2) {
        stateChanges.b = 'someValue 2';
      }
      this.setState(
        { ...stateChanges } as Pick<IMyComponentState, keyof IMyComponentState>,
        () => this.doSomethingThatDependsOnState()
      );
    }
    

    【讨论】:

    • 谢谢!回覆。传播this.state - 这是我能想到的唯一方法在那里有所需的Pick 类型(我的stateChangesPartial)。 (感谢您的链接!)
    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 2021-01-24
    • 2022-11-29
    • 2018-09-08
    • 2016-08-07
    • 2017-03-22
    • 1970-01-01
    相关资源
    最近更新 更多