[英]Problem with typing a custom hook React/Typescript
I'm having trouble with typing in the following Hook:我在输入以下 Hook 时遇到问题:
import { SetStateAction, useCallback, useEffect, useRef, useState } from 'react';
type Callback<T> = (value?: T) => void;
type DispatchWithCallback<T> = (value: T, callback?: Callback<T>) => void;
function useStateCallback<T>(initialState: T | (() => T)): [T, DispatchWithCallback<SetStateAction<T>>] {
const [state, _setState] = useState(initialState);
const callbackRef = useRef<Callback<T>>();
const isFirstCallbackCall = useRef<boolean>(true);
const setState = useCallback((setStateAction: SetStateAction<T>, callback?: Callback<T>): void => {
callbackRef.current = callback;
_setState(setStateAction);
}, []);
useEffect(() => {
if (isFirstCallbackCall.current) {
isFirstCallbackCall.current = false;
return;
}
callbackRef.current?.(state);
}, [state]);
return [state, setState];
}
export default useStateCallback;
interface InitialState {
firstName: string
lastName: string
}
No Typescript errors:没有 Typescript 错误:
const [state, setState] = useStateCallback<InitialState>({ firstName: 'Bob', lastName: 'Donovan'});
setState({ firstName: 'Claire', lastName: 'Donovan'}, (curState) => {
console.log(curState) // => { firstName: 'Claire', lastName: 'Donovan'}
});
Typescript error in console.log(curState.firstName)
: console.log(curState.firstName)
中的 Typescript 错误:
Property 'firstName' does not exist on type 'SetStateAction'.类型“SetStateAction”上不存在属性“firstName”。 Property 'firstName' does not exist on type '(prevState: InitialState) => InitialState'.类型“(prevState:InitialState)=> InitialState”上不存在属性“firstName”。
const [state, setState] = useStateCallback<InitialState>({ firstName: 'Bob', lastName: 'Donovan'});
setState({ firstName: 'Claire', lastName: 'Donovan'}, (curState) => {
console.log(curState.firstName) // => 'Claire'
});
What is wrong with the typing?打字有什么问题?
Looks like there're a few typings should be defined again from my understanding:根据我的理解,看起来应该重新定义一些类型:
// The 1st argument would take `T` or `(prevState: T) => T`
type DispatchWithCallback<T> = (value: SetStateAction<T>, callback?: Callback<T>) => void;
// so then `DispatchWithCallback` should only take `T`
function useStateCallback<T>(initialState: T | (() => T)): [T, DispatchWithCallback<T>] {
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.