React + TypeScript-如何通过一组“动态”更改来更新单个对象的状态

时间:2020-01-14 15:57:20

标签: reactjs typescript setstate tslint

我想在条件更新列表的末尾更新状态,并累积要立即提交的更改(以避免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<IMyComponentState, "a" | "b" | "c">类型的对象,但这需要我预先指定(并预测)要更改的属性,这是不可能的。我听说React的差异算法会检查引用,但是我仍然担心将整个state对象放在setState中会增加额外的开销或不必要。

1 个答案:

答案 0 :(得分:1)

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

第二,setState的类型故意不使用Partial<T>,这是因为在键上明确设置undefined 会执行状态更新,因此它使用PickGitHub issue here talking more about it

要解决此问题,您可以将状态更新投射到Pick<IMyComponentState, keyof IMyComponentState>;

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