Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 使用TypeScript在useState React钩子上设置类型_Reactjs_Typescript_React Hooks - Fatal编程技术网

Reactjs 使用TypeScript在useState React钩子上设置类型

Reactjs 使用TypeScript在useState React钩子上设置类型,reactjs,typescript,react-hooks,Reactjs,Typescript,React Hooks,我正在迁移React with TypeScript项目以使用钩子特性(React v16.7.0-alpha),但我不知道如何设置分解结构元素的类型 以下是一个例子: interface IUser { name: string; } ... const [user, setUser] = useState({name: 'Jon'}); 我想强制user变量的类型为IUser。我唯一成功的尝试是分两个阶段进行:键入,然后初始化: let user: IUser; let setUser

我正在迁移React with TypeScript项目以使用钩子特性(React v16.7.0-alpha),但我不知道如何设置分解结构元素的类型

以下是一个例子:

interface IUser {
  name: string;
}
...
const [user, setUser] = useState({name: 'Jon'});
我想强制
user
变量的类型为
IUser
。我唯一成功的尝试是分两个阶段进行:键入,然后初始化:

let user: IUser;
let setUser: any;
[user, setUser] = useState({name: 'Jon'});
但我相信有更好的办法。另外,
setUser
应该初始化为一个函数,该函数将
IUser
作为输入,并且不返回任何内容

另外,值得注意的是,使用
const[user,setUser]=useState({name:'Jon})工作正常,但我想利用TypeScript在init上强制执行类型检查,特别是如果它依赖于一些道具的话

谢谢你的帮助。

用这个

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

请参见

第一个
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>
    ) 
}
import-React,{useState,Dispatch}来自“React”;
接口IUser{
名称:字符串;
}
export const yourComponent=(setUser:Dispatch)=>{
const[user,setUser]=useState({name:'Jon'});
const clickHander=(stateSetter:Dispatch)=>{
stateSetter({name:'Jane'});
}
返回(
{clickHander(setUser)}>更改名称
) 
}

请参见此图。

您还可以在之前声明初始状态,然后可以随时调用它:

type User = typeof initUser;
const initUser = {name: 'Jon'}
...
const [user, setUser] = useState<User>(initUser);
type User=typeof initUser;
const initUser={name:'Jon'}
...
const[user,setUser]=useState(initUser);
关于I接口前缀:

//导入FunctionComponent旁边的useState
从'React'导入React,{FunctionComponent,useState};
//我们的组件道具接受一个数字作为初始值
常量计数器:FunctionComponent=({initial=0})=>{
//既然我们在这里传递了一个数字,那么点击就是一个数字。
//setClicks是一个接受数字或函数返回的函数
//数
const[clicks,setClicks]=使用状态(初始);
返回
点击:{Clicks}

设置单击次数(单击次数+1)}>+ setClicks(clicks-1)}>- }
在过去的6个月里,我已经参考了这个答案大约6次。这个答案很有效,但似乎对替代IUser的内容完全不敏感。我可以在那里放置任何东西,后续使用的
setUser
通过类型检查通过。@或者我不可以,你不能在那里放置任何东西,你只能在那里放置一个与
IUser
兼容的对象,即具有相同属性的对象。这叫做鸭子打字。@JoãoMarcosGris
typemytype=MyObj[]
然后
useState
@Joey Baruch不,我们不是:-)试试看。然后查看类型定义,您将看到
useState
返回一个类型良好的元组,该元组被分配给
[user,setUser]
,TypeScript不难理解变量应该与元组成分的类型相同。不知道我是把事情弄清楚了还是把你弄糊涂了。
// 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>
      </>
    }