React w TypeScript:为什么当 useState 带有回调作为更新器时,状态的类型会丢失

作者:编程家 分类: reactjs 时间:2025-09-15

为什么当 useState 带有回调作为更新器时,状态的类型会丢失

在使用 React 和 TypeScript 开发应用程序时,我们经常会使用 useState 这个钩子函数来管理组件的状态。useState 函数接受一个初始状态的值,并返回一个数组,其中第一个元素是当前状态的值,第二个元素是更新状态的函数。然而,当我们在使用 useState 函数时,如果将一个回调函数作为更新器传递进去,我们会发现状态的类型会丢失。

这个问题的根本原因是 TypeScript 的类型系统对 useState 函数的类型推断不够智能。当我们将回调函数作为更新器传递给 useState 函数时,TypeScript 无法正确推断出状态的类型。这主要是因为 useState 函数的类型定义是泛型的,它可以接受任意类型的状态。而当我们传递一个回调函数作为更新器时,TypeScript 无法确定回调函数的返回值和状态的类型是否一致,从而导致类型丢失。

为了更好地理解这个问题,让我们来看一个简单的示例代码:

typescript

import React, { useState } from "react";

const Counter: React.FC = () => {

const [count, setCount] = useState(0);

const increment = () => {

setCount((prevCount) => prevCount + 1);

};

return (

Count: {count}

);

};

export default Counter;

在上面的代码中,我们定义了一个名为 Counter 的函数组件,并使用 useState 函数来管理一个名为 count 的状态。我们将 count 的初始值设置为 0,并指定它的类型为 number。

接下来,我们定义了一个名为 increment 的函数,它使用 setCount 函数来更新 count 的值。注意,我们将一个回调函数作为 setCount 的参数,这个回调函数会接收到前一个状态的值 prevCount,并返回一个新的状态值。

然而,如果我们尝试在 increment 函数中添加类型注解,如下所示:

typescript

const increment = (): void => {

setCount((prevCount: number) => prevCount + 1);

};

我们会发现 TypeScript 报错,提示我们无法将类型 "(prevCount: number) => number" 分配给类型 "SetStateAction"。这是因为 TypeScript 无法推断出回调函数的返回值和状态的类型一致。

为了解决这个问题,我们可以使用类型断言来告诉 TypeScript 回调函数的返回值是与状态类型一致的。修改后的代码如下:

typescript

const increment = (): void => {

setCount((prevCount) => prevCount + 1) as number;

};

通过使用类型断言,我们告诉 TypeScript 回调函数的返回值是一个 number 类型,从而解决了类型丢失的问题。

在使用 React 和 TypeScript 开发应用程序时,当我们将回调函数作为 useState 的更新器时,状态的类型会丢失。这是因为 TypeScript 的类型推断对 useState 函数不够智能,无法确定回调函数的返回值和状态的类型是否一致。为了解决这个问题,我们可以使用类型断言来告诉 TypeScript 回调函数的返回值是与状态类型一致的。