We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
hook结合typescript可以说是很香了。本文主要介绍hook结合typescript 如何使用,享受ts带给我们的编辑器提示和类型约束
hook
useState
useState如果初始值不是null/undefined的话,是具备类型推导能力的,根据传入的初始值推断出类型;初始值是 null/undefined的话则需要传递类型定义才能进行约束。一般情况下,还是推荐传入类型(通过useState的第一个泛型参数)。
null/undefined
// 这里ts可以推断 value的类型并且能对setValue函数调用进行约束 const [value, setValue] = useState(0); interface MyObject { foo: string; bar?: number; } // 这里需要传递MyObject才能约束 value, setValue // 一般情况下推荐传入类型 const [value, setValue] = useState<MyObject>(null);
useContext
useContext一般根据传入的Context的值就可以推断出返回值。不需要显示传递类型
type Theme = 'light' | 'dark'; // 我们在createContext就传了类型了 const ThemeContext = createContext<Theme>('dark'); const App = () => ( <ThemeContext.Provider value="dark"> <MyComponent /> </ThemeContext.Provider> ) const MyComponent = () => { // useContext根据ThemeContext推断出类型,这里不需要显示传 const theme = useContext(ThemeContext); return <div>The theme is {theme}</div>;
useEffect
useLayoutEffect
没有返回值,无需传递类型
useCallback
useMemo
useMemo无需传递类型,根据函数的返回值就能推断出类型
useCallback无需传递类型,根据函数的返回值就能推断出类型。但是注意函数的入参需要定义类型,不然就是推断为any了!
const value = 10; // 推断出result是number类型 const result = useMemo(() => value * 2, [value]); const multiplier = 2; // 推断出 (value: number) => number // 注意函数入参value需要定义类型 const multiply = useCallback((value: number) => value * multiplier, [multiplier]);
useRef
useRef传非空初始值的时候可以推断类型,同样也可以通过传入第一个泛型参数来定义类型,约束ref.current的类型。
ref.current
const MyInput = () => { // 这里约束inputRef是一个html元素 const inputRef = useRef<HTMLInputElement>(null); return <input ref={inputRef} /> }
// 自动推断出 myNumberRef.current 是number类型 const myNumberRef = useRef(0); myNumberRef.current += 1;
useReducer
只需要对传入useReducer的reducer函数的入参state和action进行类型约束就能够推断出来
state
action
interface State { value: number; } type Action = | { type: 'increment' } | { type: 'decrement' } | { type: 'incrementAmount'; amount: number }; const counterReducer = (state: State, action: Action) => { switch (action.type) { case 'increment': return { value: state.value + 1 }; case 'decrement': return { value: state.value - 1 }; case 'incrementAmount': return { value: state.value + action.amount }; default: throw new Error(); } }; // 这里可以推断出state为State类型 const [state, dispatch] = useReducer(counterReducer, { value: 0 }); //能够约束传入dispatch的参数,符合Action类型 dispatch({ type: 'increment' }); dispatch({ type: 'decrement' }); dispatch({ type: 'incrementAmount', amount: 10 }); // TypeScript compilation error dispatch({ type: 'invalidActionType' });
useImperativeHandle
useImperativeHandle一般比较少用,一般用来选择函数组件对外暴露ref属性被调用,需要配合forwardRef使用。
forwardRef
如下例子。需要定义对外暴露的接口MyInputHandles,函数组件使用React.RefForwardingComponent对外暴露的接口调用作为泛型参数。然后就会得到约束了
MyInputHandles
React.RefForwardingComponent
// MyInputHandles 需要给父组件的useRef作为类型使用 和 RefForwardingComponent作为泛型参数传入约束 export interface MyInputHandles { focus(): void; } // 使用RefForwardingComponent 类型进行定义组件,第一个泛型参数是对外暴露的handle,第二个是Props const MyInput: RefForwardingComponent<MyInputHandles, MyInputProps> = ( props, ref ) => { const inputRef = useRef<HTMLInputElement>(null); useImperativeHandle(ref, () => ({ // 这里的返回会自动使用MyInputHandles进行类型约束 focus: () => { if (inputRef.current) { inputRef.current.focus(); } }, })); return <input {...props} ref={inputRef} />; }; // 函数组件必须使用forwardRef才能让外部组件使用该组件的ref export default forwardRef(MyInput);
// 父组件 const Autofocus = () => { // 能够约束 myInputRef.current的类型 const myInputRef = useRef<MyInputHandles>(null); useEffect(() => { if (myInputRef.current) { myInputRef.current.focus(); } }); return <MyInput ref={myInputRef} /> }
参考:
React Hooks in TypeScript
The text was updated successfully, but these errors were encountered:
No branches or pull requests
useState
useState
如果初始值不是null/undefined
的话,是具备类型推导能力的,根据传入的初始值推断出类型;初始值是null/undefined
的话则需要传递类型定义才能进行约束。一般情况下,还是推荐传入类型(通过useState的第一个泛型参数)。useContext
useContext
一般根据传入的Context的值就可以推断出返回值。不需要显示传递类型useEffect
useLayoutEffect
没有返回值,无需传递类型
useCallback
useMemo
useMemo
无需传递类型,根据函数的返回值就能推断出类型useCallback
无需传递类型,根据函数的返回值就能推断出类型。但是注意函数的入参需要定义类型,不然就是推断为any了!useRef
useRef
传非空初始值的时候可以推断类型,同样也可以通过传入第一个泛型参数来定义类型,约束ref.current
的类型。useReducer
只需要对传入
useReducer
的reducer函数的入参state
和action
进行类型约束就能够推断出来useImperativeHandle
useImperativeHandle
一般比较少用,一般用来选择函数组件对外暴露ref属性被调用,需要配合forwardRef
使用。如下例子。需要定义对外暴露的接口
MyInputHandles
,函数组件使用React.RefForwardingComponent
对外暴露的接口调用作为泛型参数。然后就会得到约束了参考:
React Hooks in TypeScript
The text was updated successfully, but these errors were encountered: