使用TypeScript在useState React Hook上设置类型


88

我正在迁移带有TypeScript的React项目以使用挂钩功能(React v16.7.0-alpha),但是我不知道如何设置已分解元素的类型。

这是一个例子:

interface IUser {
  name: string;
}
...
const [user, setUser] = useState({name: 'Jon'});

我想强制user变量为type IUser。我唯一成功的试用是分两个阶段进行的:键入,然后初始化:

let user: IUser;
let setUser: any;
[user, setUser] = useState({name: 'Jon'});

但是我敢肯定有更好的方法。另外,setUser应将其初始化为以aIUser作为输入且什么都不返回的函数。

另外,值得注意的是,const [user, setUser] = useState({name: 'Jon'});不进行任何初始化就可以正常使用,但是我想利用TypeScript强制对init进行类型检查,特别是如果它依赖于某些道具的话。

谢谢你的帮助。

Answers:


172

用这个

const [user, setUser] = useState<IUser>({name: 'Jon'});

在此处查看相应的类型:https : //github.com/DefinitelyTyped/DefinitelyTyped/blob/8a1b68be3a64e5d2aa1070f68cc935d668a976ad/types/react/index.d.ts#L844


那正是我想要的。感谢@Nurbol
htaidirt

4
在过去的6个月中,我已提及此答案约6次
AlfonsoPérez'19

1
@orome不,您不能在此处放置任何东西,您只能在其中放置与兼容的对象IUser,即具有相同属性的对象。这就是鸭子打字。
Nurbol Alpysbayev

1
@JoãoMarcosGristype MyType = MyObj[]; 然后useState<MyType>
Nurbol Alpysbayev,

1
@JoeyBaruch不,我们不是:-)试试吧。然后查看类型定义,您将看到useState返回一个类型正确的元组,该元组已分配给[user, setUser]它,并且TypeScript并不难理解变量应该与元组组成部分具有相同的类型。不知道我是清理还是进一步困惑了您。
Nurbol Alpysbayev

18

首先useState需要一个通用名称,它将是您的IUser。如果然后要传递由返回的第二个重构元素,则useState需要导入Dispatch。考虑示例的扩展版本,该版本具有点击处理程序:

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

interface IUser {
  name: string;
}

export const yourComponent = (setUser: Dispatch<IUser>) => {

    const [user, setUser] = useState<IUser>({name: 'Jon'});

    const clickHander = (stateSetter: Dispatch<IUser>) => {
        stateSetter({name : 'Jane'});
    }

    return (
         <div>
            <button onClick={() => { clickHander(setUser) }}>Change Name</button>
        </div>
    ) 
}

看到这个答案



0

https://fettblog.eu/typescript-react/hooks/

// import useState next to FunctionComponent
    import React, { FunctionComponent, useState } from 'react';
    
    // our components props accept a number for the initial value
    const Counter:FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
      // since we pass a number here, clicks is going to be a number.
      // setClicks is a function that accepts either a number or a function returning
      // a number
      const [clicks, setClicks] = useState(initial);
      return <>
        <p>Clicks: {clicks}</p>
        <button onClick={() => setClicks(clicks+1)}>+</button>
        <button onClick={() => setClicks(clicks-1)}>-</button>
      </>
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.