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

如何为作为Context值的useReducer添加TypeScript类型?

问题:为useReducer返回值的Context添加类型的最佳方式

我想把useReducer的返回值作为StateContext.Provider的值传递,但在使用useContext(StateContext)消费时报错:

Type '[initialStateType, Dispatch] | null' is not an array type

我找到一个临时解决方法:

export const StateContext =  createContext([] as unknown as [initialStateType, Dispatch<Action>]);

但不确定这种类型断言是不是最优方案,想知道为作为Context值的useReducer添加类型的最佳方式是什么?

相关代码

stateProvider.tsx

export const StateContext =  createContext< [initialStateType, Dispatch<Action>] | null>(null);

export const StateProvider = ({ reducer, initialState, children }: StateProviderProps) => {
  return (
    <StateContext.Provider value={useReducer(reducer, initialState)}>
      {children}
    </StateContext.Provider>
  )
}

Product.tsx

export const Product = ({id,title,image,price, rating}: ProductProps) => {
    const [state,dispatch] = useContext(StateContext); // 报错: Type '[initialStateType, Dispatch<Action>] | null' is not an array type.
}

最佳解决方案

1. 移除Context类型中的null,提供合法初始值

当前Context类型包含null,但Provider实际传递的是useReducer返回的合法数组,导致消费时必须处理null分支,触发类型错误。直接给Context提供符合类型的初始值即可:

// 定义空dispatch函数作为默认值
const defaultDispatch: Dispatch<Action> = () => {};

// 用实际的initialState实例和默认dispatch初始化Context
export const StateContext = createContext<[initialStateType, Dispatch<Action>]>([
  initialState,
  defaultDispatch
]);

这样Context类型不再包含null,组件中直接解构即可,不会出现类型报错。

2. 封装自定义Hook消费Context

封装自定义Hook可以简化消费逻辑,还能防止组件在Provider外部使用时出现错误:

export const useStateContext = () => {
  const context = useContext(StateContext);
  // 确保组件在Provider内部使用
  if (!context) {
    throw new Error('useStateContext 必须在 StateProvider 内部使用');
  }
  return context;
};

组件中使用方式:

const [state, dispatch] = useStateContext();

3. 优化StateProvider的泛型类型定义

让StateProvider支持泛型,约束reducer和initialState的类型匹配,提升复用性:

import { Reducer, ReactNode } from 'react';

type StateProviderProps<S, A> = {
  reducer: Reducer<S, A>;
  initialState: S;
  children: ReactNode;
};

export const StateProvider = <S, A>({ reducer, initialState, children }: StateProviderProps<S, A>) => {
  const value = useReducer(reducer, initialState);
  return (
    <StateContext.Provider value={value}>
      {children}
    </StateContext.Provider>
  );
};

内容的提问来源于stack exchange,提问作者Aparichit_Coder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 05:27:41