Passing useState as props in typescript

杀马特。学长 韩版系。学妹 提交于 2021-02-15 11:44:18

问题


Say I have a parent component with two child components:

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

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

Now how would I go about setting the type correctly in MyChildComponent2?

This is what I've come up with so far:

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

Is the type for setMyvar correct? Or should it be something else?


回答1:


The type that would match the function returned from invoking useState would be:

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

If we look at the type definition file from DefinitelyTyped [1], we can see that the second type in the return type is a dispatch:

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

Thus the generic type provided is passed through to SetStateAction<S>, which is defined as:

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

So essentially, an interface for your component would be the following:

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

As @Retsam said, it's best to use React's exported types:

import { Dispatch, SetStateAction } from "react";

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

References: [1] https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L845




回答2:


Dispatch & SetStateAction types

As @Retsam mentioned, you can also import and use the types Dispatch and SetStateAction from React:

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

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

Bonus

When I find myself frequently using this, I create a type alias to help with readability

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

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

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

hope this helps.




回答3:


Adding onto @fiz's comment, his code of block was slightly not working for me:

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

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

I had to set setMyVar: Dispatch<SetStateAction<boolean>> (there was one too many brackets)



来源:https://stackoverflow.com/questions/56028635/passing-usestate-as-props-in-typescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!