【问题标题】:Passing useState as props in typescript在打字稿中将 useState 作为道具传递
【发布时间】:2019-09-25 11:20:46
【问题描述】:

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

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 的类型是否正确?还是应该换成别的?

【问题讨论】:

标签: reactjs typescript react-hooks react-props


【解决方案1】:

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

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

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

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

因此提供的泛型类型被传递给SetStateAction&lt;S&gt;,其定义为:

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

【讨论】:

  • 他们可以从 React 中导入 DispatchSetStateAction&lt;S&gt; 类型,所以他们的类型可以是 {myVar: boolean, setMyVar?: Dispatch&lt;SetStateAction&lt;boolean&gt;&gt;}
  • @Retsam,请考虑将其写为答案而不是评论。我是打字稿、反应和钩子的新手——同时有太多的移动部件。这种方法有什么缺点吗?
  • 是的,谢谢@Retsam... TS 停止对我尖叫并删除了 10 个警告
  • 这是金子!谢谢?
  • 如何让它更短? {myVar: boolean, setMyVar?: Dispatch&lt;boolean&gt;}
【解决方案2】:

Dispatch 和 SetStateAction 类型

正如@Retsam 提到的,您还可以从 React 导入和使用 DispatchSetStateAction 类型:

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>,
) => {...};

希望这会有所帮助。

【讨论】:

    【解决方案3】:

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

    import React, { Dispatch, SetStateAction } from 'react';
    
    const MyChildComponent1 = (
      myVar: boolean,
      setMyVar: Dispatch<SetStateAction<<boolean>>
    ) => {...};
    

    我必须设置setMyVar: Dispatch&lt;SetStateAction&lt;boolean&gt;&gt;(括号太多了)

    【讨论】:

    • 感谢您纠正语法错误。顺便说一句,您下次可以针对此类小错误或其他边际改进来编辑答案,而不是创建一个完整的其他帖子。欢迎加入社区!
    猜你喜欢
    • 2023-02-23
    • 2022-08-12
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 2021-06-17
    • 2021-12-09
    • 1970-01-01
    • 2022-11-05
    相关资源
    最近更新 更多