React 只监听状态浅拷贝的更新,如果对对象内部的属性值进行更新,则不会触发 React 更新,因为这并不会导致对象引用的改变,React 则认为对象没有发送变化

方法 1:覆写对象

// 直接修改属性值无法检测到结构变更
person.name = "John" // 无效 

const App: React.FC = () => {
  const [person, setPerson] = useState<Person>({
    name: "Andrew",
    age: 12
  });

  const modify = () => {
    **const newPerson = {
      ...person,
      age: 20
    };**

    setPerson(newPerson);
  };

  return (
    <div>
      <h1>{person.name}</h1>
      <h1>{person.age}</h1>
      <button onClick={modify}>modify info</button>
    </div>
  );
};

方法2:解构赋值

这里, person 的属性被修改了,直接解构赋值相当于传入了一个新对象。其原理和上一个方法是一样的

const modify = () => {
  person.age = 20;

  setPerson({...person});
};

方法3:调用 Object.assign API

Object.assign 会返回一个新对象,原理还是一样的

const modify = () => {
  person.age = 20;

  setPerson(Object.assign({}, person));
};

以上三个方法都是创建一个新的对象引用