如何在 React/TypeScript 中使用钩子进行部分状态更新

And*_*ndy 4 typescript reactjs

我正在尝试将具有状态的组件从基于类的组件转换为功能组件,我的状态类如下所示:

class Person {
    name:string = ""
    email:string = ""
}
Run Code Online (Sandbox Code Playgroud)

我的类组件如下所示:

class Component1 extends React.Component<{}, Person> {
    state: Person = new Person();
    foo() {
        this.setState ({name:"me"});
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以看到 setState 调用仅更新状态的一个属性。将其转换为功能组件如下所示:

function Component() {
    const [state, setState] = useState(new Person())
    function foo() {
        setState({name:"me"})
    }
}
Run Code Online (Sandbox Code Playgroud)

但我在 setState 调用上遇到编译错误

Argument of type '{ name: string; }' is not assignable to parameter of type 'SetStateAction<Person>'.
  Property 'email' is missing in type '{ name: string; }' but required in type 'Person'.
Run Code Online (Sandbox Code Playgroud)

显然,如果我使用,问题就会消失setState({...state, name:"me"}),但如果这只是 TypeScript 绑定中的一个小故障,我不想这样做。

TLa*_*add 6

React 文档对此有注释:

笔记

与类组件中的 setState 方法不同,useState 不会自动合并更新对象。您可以通过将函数更新器形式与对象扩展语法相结合来复制此行为:

setState(prevState => {
// Object.assign 也可以工作
return {...prevState, ...updatedValues}; });

另一个选项是 useReducer,它更适合管理包含多个子值的状态对象。

所以你的选择是:

  1. 使用像上面这样的扩展语法。
  2. 将您的 person 状态分成两个单独的useStates。
  3. 使用 useReducer。但这仍然需要将先前的状态扩展到返回值中。

  • 谢谢 - 我从来没有想到你可以多次调用 useState (3认同)