简体   繁体   English

键入自定义钩子 React/Typescript 时出现问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM