将useState作为属性传递到typescript中

edqdpe6u  于 2022-11-18  发布在  TypeScript
关注(0)|答案(6)|浏览(126)

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

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的类型是否正确?或者应该是其他类型?

ycggw6v2

ycggw6v21#

与调用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

myzjeezk

myzjeezk2#

分派和设定状态动作型别

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

希望这对你有帮助。

aor9mmx1

aor9mmx13#

再加上@fiz的评论,他的block代码对我来说有点不起作用:

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

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

我不得不设置setMyVar: Dispatch<SetStateAction<boolean>>(括号太多)

wqnecbli

wqnecbli4#

也可以像这样使用Interface和React组件来完成。

主组件.tsx

Main中定义的useState组件的赋值在子组件中完成,当该字段被触发时,将运行useEffect中的代码。

import React, { useEffect } from 'react';
import Login from './views/Login/index';

const App: React.FunctionComponent = () => {
    const [isAuthenticated, setAuthenticatedStatus] = React.useState(false);

    useEffect(() => {
        if (isAuthenticated)
            window.location.href = "<redirect url>";
    }, [isAuthenticated]);

    return (<Login setLoginStatus={setAuthenticatedStatus} />)
};

export default App;

子组件.tsx

import { Dispatch, SetStateAction, FunctionComponent } from 'react';
import authService from '../../apiServices/authService';

interface IProps {
   setLoginStatus: Dispatch<SetStateAction<boolean>>;
}

const Login: FunctionComponent<IProps> = (props: IProps) => {

   const login = async (username: string, password: string) => {
      const response = await authService.authenticateUser(username, password);

      if (response && response.statusCode == 200 && response.result.accessToken) {
         props.setLoginStatus(true);
      }
      else {
         // ...
      }
   };

   return (
      <>
         ...
      </>
   );
};

export default Login;
lnlaulya

lnlaulya5#

我的子组件1.tsx

设置类型属性如下:
从“react”导入React
类型属性= {
myVar:布尔值;
第一步:在第一步中,将第一步中的所有操作都分配给第二步中的操作。

我的子组件常量=({我的变量,设置我的变量}:道具)=〉{
...您的密码...
}

pinkon5k

pinkon5k6#

我发现其他的答案有点令人困惑,所以以下是对我有效的答案:
在parent.ts中示例化useState():

const [someState, setSomeState] = useState<stateType>(initialState)

将setSomeState()传递给child.ts:

<Child
    setSomeState={setSomeState}
/>
  • 请确保只传递名称而不传递()*

在child.ts中设置这样的Props:

import Dispatch from 'react'

interface Props {setSomeState: Dispatch<stateType>}

相关问题