如何使用泛型正确设置 react useState
Posted
技术标签:
【中文标题】如何使用泛型正确设置 react useState【英文标题】:How to correctly set react useState using generics 【发布时间】:2021-11-11 18:05:00 【问题描述】:核心问题 - 我在哪里搞砸了我的 useState
const [data, setData] = useState<IAssetGetManyResponseDto<IAssetResponseDto>>();
所以我作为道具发送的data
对象是undefined
?
我的(正常运行的)api 调用如下所示
export const getAllAssets = async (
): Promise<IAssetGetManyResponseDto<IAssetResponseDto>> =>
console.log("get all assets ran in api.ts!")
const response = await amsApiClient.get(ASSET_ENDPOINT(),
params:
limit: 1000
);
console.log("logging response data "+JSON.stringify(response.data))
return response.data;
;
这里是使用的类型:
export interface IAssetGetManyResponseDto<T>
items: T[];
totalCount: number;
export interface IAssetResponseDto
id: string | null;
name: string | null;
type: string | null;
url: string | null;
// metadata: IMetadataObj| null;
tags: Array<string> | null;
thumbnailImageURL: string | null;
createdAt: number | null;
updatedAt: number | null;
这是进行调用的组件,以显示上下文
export const AssetManagementTable = () =>
const [data, setData] = useState<IAssetGetManyResponseDto<IAssetResponseDto>>();
const getAssets = async () =>
console.log("getAssets ran!")
const assets = await getAllAssets();
console.log("logging data from asset managment table " + data)
console.log("logging assets from asset managment table " + assets)
setData(assets)
useEffect(() =>
getAssets()
, []);
return (
<div>
<NewAssetTable items=data />
</div>
);
;
在我的应用程序的其他地方,当我向下传递道具并引用props.items.map((item: any). => ...
时,我得到了undefined
。
更具体地说,TypeError: Cannot read properties of undefined (reading 'map')
我是否通过不正确地指定类型而弄乱了 useState 的参数?
谢谢!
【问题讨论】:
【参考方案1】:看起来type definitions for React.useState
有点不安全。对于没有参数的变体,它们不会使用 undefined
增加返回类型。
所以,如果你告诉状态将始终包含IAssetGetManyResponseDto<IAssetResponseDto>
,TS 编译器就会相信。
将鼠标悬停在 data
上,查看它有 IAssetGetManyResponseDto<IAssetResponseDto>
,而它应该是 IAssetGetManyResponseDto<IAssetResponseDto> | undefined
。
解决方法:
useState<IAssetGetManyResponseDto<IAssetResponseDto> | undefined>()
useState<IAssetGetManyResponseDto<IAssetResponseDto>>(someFunctionalMockOfYourData)
【讨论】:
谢谢@Zbigniew!我一直在尝试执行您提到的第二个选项useState<IAssetGetManyResponseDto<IAssetResponseDto>>(someFunctionalMockOfYourData)
。我只是不知道如何模拟数据以传递 useState!如果这有助于弄清楚如何在功能上模拟数据,则将类型接口添加到问题中。
经典的“加载”问题。您基本上有 3 个选择 1) 不显示 NewAssetTable
,并显示一些“正在加载...”占位符。 2) 确保 NewAssetTable
与 data=undefined
一起使用 3) 准备“空模拟” ...现在是你的电话,当你有正确的打字时:)
谢谢!但是空的模拟会是什么样子?我如何将它传递给 useState?
const [data, setData] = useState<IAssetGetManyResponseDto<IAssetResponseDto>>( items: [], totalCount: number );
?
是的,看起来items: [], totalCount: 0
适合您的情况。但是,我不了解您的应用。您必须决定在数据仍然不可用时显示什么。以上是关于如何使用泛型正确设置 react useState的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React 中正确使用 useState 钩子和 typescript?
在 React 中,如何使用 hook useState 来设置数据?
使用 React 的 useState 钩子时输入可空状态的正确方法
如何使用 Typescript 和 useState 将类型对象设置为 React 的初始值?