如何在TypeScript中使用useContext?请将JS代码转为TS示例
将React Context API的JavaScript代码转换为TypeScript
下面是转换后的TypeScript代码,附带关键步骤的说明:
1. 定义Context类型接口
首先明确上下文包含的所有状态和方法的类型,这是TypeScript类型安全的核心:
import React, { createContext, useState, useContext, ReactNode } from "react"; // 定义Context的类型接口 interface StateContextType { sidebar: boolean; setSidebar: React.Dispatch<React.SetStateAction<boolean>>; activeMenu: boolean; setActiveMenu: React.Dispatch<React.SetStateAction<boolean>>; screenSize: number | undefined; setScreenSize: React.Dispatch<React.SetStateAction<number | undefined>>; }
2. 创建带类型的Context
给createContext指定刚才定义的类型,由于初始值暂时无法提供有效内容,设为null,后续在自定义hook中处理非空判断:
const stateContext = createContext<StateContextType | null>(null);
3. 编写类型化的ContextProvider组件
给组件的children属性指定ReactNode类型,确保只有合法的React子元素可以传入:
export const ContextProvider = ({ children }: { children: ReactNode }) => { const [sidebar, setSidebar] = useState<boolean>(false); const [activeMenu, setActiveMenu] = useState<boolean>(true); // 明确screenSize的类型为number或undefined const [screenSize, setScreenSize] = useState<number | undefined>(undefined); return ( <stateContext.Provider value={{ sidebar, setSidebar, screenSize, setScreenSize, activeMenu, setActiveMenu, }} > {children} </stateContext.Provider> ); };
4. 类型化的自定义Hook
在自定义hook中添加非空检查,确保返回的上下文不为空,避免后续使用时出现类型错误:
export const useStateContext = () => { const context = useContext(stateContext); // 如果上下文未被Provider包裹,抛出错误提示 if (!context) { throw new Error("useStateContext must be used within a ContextProvider"); } return context; };
完整代码
import React, { createContext, useState, useContext, ReactNode } from "react"; interface StateContextType { sidebar: boolean; setSidebar: React.Dispatch<React.SetStateAction<boolean>>; activeMenu: boolean; setActiveMenu: React.Dispatch<React.SetStateAction<boolean>>; screenSize: number | undefined; setScreenSize: React.Dispatch<React.SetStateAction<number | undefined>>; } const stateContext = createContext<StateContextType | null>(null); export const ContextProvider = ({ children }: { children: ReactNode }) => { const [sidebar, setSidebar] = useState<boolean>(false); const [activeMenu, setActiveMenu] = useState<boolean>(true); const [screenSize, setScreenSize] = useState<number | undefined>(undefined); return ( <stateContext.Provider value={{ sidebar, setSidebar, screenSize, setScreenSize, activeMenu, setActiveMenu, }} > {children} </stateContext.Provider> ); }; export const useStateContext = () => { const context = useContext(stateContext); if (!context) { throw new Error("useStateContext must be used within a ContextProvider"); } return context; };
关键说明
- 类型接口
StateContextType明确了上下文中每个属性的类型,包括状态变量和对应的setter方法(React.Dispatch<React.SetStateAction<T>>是useState返回setter的标准类型)。 - 给
createContext指定类型并设初始值为null,同时在自定义hook中添加非空检查,确保组件使用hook时一定处于Provider的包裹范围内,避免运行时错误。 - 给每个
useState显式指定状态类型,虽然TS有时能自动推断,但显式指定更清晰,也能避免特殊情况下的推断错误。
内容的提问来源于stack exchange,提问作者Emmanuel uzoezie
相关产品推荐
相关产品推荐

