《React 复杂state》

681 阅读2分钟

如果state里有多个数据怎么办

类组件第一层属性会自动合并

class Son extends React.Component {
  constructor() {
    super();
    this.state = {
      n: 0,
      m: 0
    };
  }
  addN() {
    this.setState({ n: this.state.n + 1 });
    // m 会被覆盖为 undefined 吗?
  }
  addM() {
    this.setState({ m: this.state.m + 1 });
    // n 会被覆盖为 undefined 吗?
  }
  render() {
    return (
      <div className="Son">
        儿子 n: {this.state.n}
        <button onClick={() => this.addN()}>n+1</button>
        m: {this.state.m}
        <button onClick={() => this.addM()}>m+1</button>
        <Grandson />
      </div>
    );
  }
}

state里有m和n。如果我想修改其中一个,只写this.setState({ n: this.state.n + 1 });,可以把n+1.同时也不会影响m。并不会因为没写m就把m覆盖掉了。

同理,当我只传一个m的新对象时,也可以不管n,React会同步

即,类组件的setState会自动合并第一层属性,必须是同为this.state下的第一层

类组件不会合并第二层属性

如果同为第二层属性,如果只修改其中一个,不管另一个,类组件不会帮你自动合并。

class Son extends React.Component {
  constructor() {
    super();
    this.state = {
      n: 0,
      m: 0,
      user: {
        name: "frank",
        age: 18
      }
    };
  }
  changeUser() {
    this.setState({
      user: {
        name: "jack"
        // age 被置空
      }
    });
  }
  render() {
    return (
      <div className="Son">
        <div>user.name: {this.state.user.name}</div>
        <div>user.age: {this.state.user.age}</div>
        <button onClick={() => this.changeUser()}>change user</button>
        <Grandson />
      </div>
    );
  }
}

user里有name和age,是第二层属性。如果setState的时候,只修改name,不管age,那就相当于把age置为了undefined。

应该在setState的时候,用...语法,把原来state的所有属性先拷贝过来,再修改你想修改的。

this.setState({
      user: {
        ...this.state.user,
        name: "jack"
      }
});

函数组件里有多个数据

const Grandson = () => {
  const [n, setN] = React.useState(0);
  const [m, setM] = React.useState(0);
  return (
    <div className="Grandson">
      孙子 n:{n}
      <button onClick={() => setN(n + 1)}>n+1</button>
      m:{m}
      <button onClick={() => setM(m + 1)}>m+1</button>
    </div>
  );
};

我们可以分开初始化。改的时候也是各自改。