React TypeScript使用Context时Provider value报ts2322类型错误如何解决
修复方案
核心错误原因
- 你定义的
IProductContext是元组类型,但给Provider的value传的是对象结构,二者类型完全不匹配 - Context定义的商品数组类型为必有的
IProductItem[],但实际useState和useQuery返回的商品数据都可能为undefined,类型不兼容 - 直接在组件顶层执行
setProducts会触发无限重渲染:状态更新触发组件重渲染,重渲染又会再次执行setProducts,进入死循环
修复代码(推荐使用对象结构Context,可读性更高)
第一步:调整Context类型定义
// 将原来的元组类型改为和传值对齐的对象类型,同时兼容undefined的情况 type IProductContext = { products: IProductItem[] | undefined; setProducts: React.Dispatch<React.SetStateAction<IProductItem[] | undefined>>; }; // 初始化Context时使用对应的对象默认值 export const ProductContext = React.createContext<IProductContext>({ products: [], setProducts: () => {} });
第二步:调整Provider内的渲染逻辑
const ProductProvider: React.FC<{ children?: React.ReactNode }> = ({children}) => { //fetching products data from a public API const getProducts = async (): Promise<IProductItem[]> => await (await fetch("https://fakestoreapi.com/products")).json(); //Retrieve the data and status using UseQuery const {data, error} = useQuery<IProductItem[]>('products', getProducts); const [products, setProducts] = React.useState<IProductItem[] | undefined>(); // 把状态更新逻辑放到useEffect中,仅当data或error变化时触发,避免无限重渲染 React.useEffect(() => { if(!error && data) { setProducts(data) } }, [data, error]) return ( <ProductContext.Provider value={{products, setProducts}}> {children} </ProductContext.Provider> ); };
可选:如果要保留原来的元组类型Context
只需要修改两处即可:
- 调整元组的类型兼容undefined:
type IProductContext = [ IProductItem[] | undefined, React.Dispatch<React.SetStateAction<IProductItem[] | undefined>> ];
- 给Provider传值时传入元组而非对象:
<ProductContext.Provider value={[products, setProducts]}>
内容的提问来源于stack exchange,提问作者Ahmed Zrouqui
相关产品推荐
相关产品推荐

