在typescript中将 useState 作为props传递

IT技术 reactjs typescript react-hooks react-props
2021-05-22 02:21:23

假设我有一个带有两个子组件的父组件:

const Parent = () => {
   const [myVar, setmyVar] = useState(false)

   return (
     <>
       <MyChildComponent1 myVar={myVar} setMyVar={setMyVar} \> 
       <MyChildComponent2 myVar={myVar} \>
     </>
   )
}

现在我将如何正确设置类型MyChildComponent2

这是我到目前为止想出的:

const MyChildComponent1 = (
  {myVar, setMyVar}: 
  {myVar: boolean, setMyVar: (value: boolean) => void}) = (...)

类型是否setMyvar正确?或者它应该是别的东西?

3个回答

与调用返回的函数相匹配的类型useState是:

setMyVar: (value: boolean | ((prevVar: boolean) => boolean)) => void;

如果我们查看DefinitelyTyped[1]中的类型定义文件,我们可以看到返回类型中的第二个类型是调度:

function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];

因此,提供的泛型类型被传递给SetStateAction<S>,其定义为:

type SetStateAction<S> = S | ((prevState: S) => S);

因此,基本上,您的组件的接口如下所示:

interface IProps {
  myVar: boolean;
  setMyVar?: (value: boolean | (prevVar: boolean) => boolean) => void;
}

正如@Retsam 所说,最好使用 React 的导出类型:

import { Dispatch, SetStateAction } from "react";

interface IProps {
  myVar: boolean;
  setMyVar?: Dispatch<SetStateAction<boolean>>;
}

参考文献:[1] https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L845

调度和 SetStateAction 类型

作为@Retsam提到的,你也可以导入和使用的类型Dispatch,并SetStateAction从阵营:

import React, { Dispatch, SetStateAction } from 'react';

const MyChildComponent1 = (
  myVar: boolean,
  setMyVar: Dispatch<SetStateAction<boolean>>
) => {...};

奖金

当我发现自己经常使用它时,我会创建一个类型别名来帮助提高可读性

import React, { Dispatch, SetStateAction } from 'react';

type Dispatcher<S> = Dispatch<SetStateAction<S>>;

const MyChildComponent1 = (
  myVar: boolean,
  setMyVar: Dispatcher<boolean>,
) => {...};

希望这可以帮助。

添加到@fiz 的评论中,他的代码块对我来说有点不起作用:

import React, { Dispatch, SetStateAction } from 'react';

const MyChildComponent1 = (
  myVar: boolean,
  setMyVar: Dispatch<SetStateAction<<boolean>>
) => {...};

我必须设置setMyVar: Dispatch<SetStateAction<boolean>>(括号太多了)