You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript自定义useStateIfMounted Hook类型错误修复方案问询

解决useStateIfMounted自定义Hook的TypeScript类型标注问题

问题背景

自定义useStateIfMounted Hook用于避免组件卸载后执行setState引发的警告,功能逻辑正常,但TypeScript类型标注存在问题:调用返回的setState方法时,出现类型错误:

Not all constituents of type 'T | ((value: SetStateAction<T>) => void)' are callable. Type 'T' has no call signatures.

需求是让Hook返回的setState方法类型与React原生useState完全一致。

错误复现代码

原Hook代码

import { useCallback, useState, useRef, useEffect } from 'react';

export function useStateIfMounted<T>(initialState: T | (() => T)) {
  const [state, setState] = useState(initialState);
  const isMounted = useRef(false);

  useEffect(() => {
    isMounted.current = true;
    return () => {
      isMounted.current = false;
    };
  }, []);

  const setStateIfMounted = useCallback(
    (value) => {
      if (isMounted.current) {
        setState(value);
      }
    },
    []
  );

  return [state, setStateIfMounted];
}

使用示例

const [count, setCount] = useStateIfMounted(0);
setCount(prev => prev + 1); // 此处触发类型错误

问题原因

TypeScript默认会将Hook返回的数组推断为联合类型数组(T | ((value: SetStateAction<T>) => void))[],而非明确的元组类型,导致调用setCount时无法正确识别其函数类型。

正确解决方案

通过明确指定Hook的返回元组类型,并复用React内置的Dispatch和SetStateAction类型,让返回的setState方法与原生类型完全对齐:

import { useCallback, useState, useRef, useEffect, SetStateAction, Dispatch } from 'react';

// 明确指定返回类型为元组:[状态值, 状态更新函数]
export function useStateIfMounted<T>(initialState: T | (() => T)): [T, Dispatch<SetStateAction<T>>] {
  const [state, setState] = useState(initialState);
  const isMounted = useRef(false);

  useEffect(() => {
    isMounted.current = true;
    return () => {
      isMounted.current = false;
    };
  }, []);

  // 给useCallback指定泛型,匹配原生setState的类型
  const setStateIfMounted = useCallback<Dispatch<SetStateAction<T>>>(
    (value) => {
      if (isMounted.current) {
        setState(value);
      }
    },
    []
  );

  return [state, setStateIfMounted];
}

关键修改点

  1. 导入React内置的SetStateAction(描述状态更新值的类型)和Dispatch(描述状态更新函数的类型);
  2. 给Hook函数添加返回类型标注[T, Dispatch<SetStateAction<T>>],明确返回的是固定顺序的元组,而非联合类型数组;
  3. 给useCallback指定泛型参数Dispatch<SetStateAction<T>>,确保回调函数的类型与原生setState完全一致。

依赖与配置确认

  • React版本:16.8+(支持Hooks)
  • TypeScript版本:4.0+(支持React内置类型)
  • tsconfig.json核心配置示例:
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "lib": ["DOM", "ES2020"],
    "module": "ESNext",
    "target": "ES2020",
    "strict": true,
    "esModuleInterop": true
  }
}

内容的提问来源于stack exchange,提问作者benard-kong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:27:13