How do I set the type of 'user' properly in useState [user, setuser], so that I dont get type error when I extract the json data in the return? React

huangapple go评论62阅读模式
英文:

How do I set the type of 'user' properly in useState [user, setuser], so that I dont get type error when I extract the json data in the return? React

问题

以下是翻译好的部分:

这是一个初学者问题,所以请不要讨厌。请尽量解释得详细一些。

程序运行得很好,但在 TypeScript 控制台中,我收到了以下错误消息。

属性 'bio' 不存在于类型 'any[]'
'use client';
import { useEffect, useState } from "react";

export default function Github(){
	const [user , setUser] = useState([]);
	let fetchUserData = () => {
		fetch("https://api.github.com/users/userName")
		.then(response => {
			return response.json()
		})
		.then(data => {
			setUser(data)
		})
	}
	useEffect( () => {
		fetchUserData()
	}, [])
	return (
		<div>
			{typeof(user.bio)}
		</div>
	)

}

当我尝试从用户中提取属性时发生了这种情况。如果我使用替代符号来获取数据,即 user['bio'],TypeScript 不会显示任何错误。

我正在尝试理解 React、Next JS 和 TypeScript。我尝试了文档和其他教程。

我还尝试在 useState 之前声明一个用户的接口,但没有效果。请给予建议!

英文:

This is a beginner question so please don't hate. Please explain as much as you can.

The program is working just fine, but in the typescript console, I am getting this error.

Property &#39;bio&#39; does not exist on type &#39;any[]&#39;.
&#39;use client&#39;;
import { useEffect, useState } from &quot;react&quot;;

export default function Github(){
	const [user , setUser] = useState([]);
	let fetchUserData = () =&gt; {
		fetch(&quot;https://api.github.com/users/userName&quot;)
		.then(response =&gt; {
			return response.json()
		})
		.then(data =&gt; {
			setUser(data)
		})
	}
	useEffect( () =&gt; {
		fetchUserData()
	}, [])
	return (
		&lt;div&gt;
			{typeof(user.bio)}
		&lt;/div&gt;
	)

}

This has happened when I am trying to extract the property from user. If I use alternative notation to grab the data, i.e, user[&#39;bio&#39;], typescript does not show any error.

I am trying to understand React, Next JS and Typescript. I tried documentation and other tutorials.

I also tried to declare an interface above useState for user, but nothing worked. Please advice !

答案1

得分: 2

最简单的方法是在调用 useState() 时提供一个通用类型参数:

// 在某处声明,可能是另一个文件
interface User {
  bio: string
}

 const [user, setUser] = useState<User>();

这将导致值为 User | undefined,所以你仍然需要检查该值不是 undefined(或使用可选链操作符):

<div>
  {user?.bio}
</div>

或者,你可以为 useState() 提供一个默认值:

// 在组件外部
const BLANK_USER: User = { bio: '' }

// 在组件内部
const [user, setUser] = useState(BLANK_USER)

个人建议使用类型参数,因为像这样使用默认值可能会变得奇怪 - 如果你的类型没有指定所有用户属性,它将是错误的,例如。

注意:在你的示例中,你将一个数组([])作为默认值传递,这是错误的。你可能想要传递一个空对象 {},但 TypeScript 不会喜欢这样做。

英文:

The easiest way is to provide a generic type parameter when calling useState():

// Declared somewhere, likely another file
interface User {
  bio: string
}

 const [user, setUser] = useState&lt;User&gt;();

This will result in the value being User | undefined, so you'll still need to check the value isn't undefined (or use optional chaining):

&lt;div&gt;
  {user?.bio}
&lt;/div&gt;

Alternatively, you can provide a default value to useState():

// outside component
const BLANK_USER: User = { bio: &#39;&#39; }

// inside component
const [user, setUser] = useState(BLANK_USER)

Personally, I'd go with providing a type argument, as using a default value like this could get weird -- it will be wrong if your type doesn't specify all properties of a user, for example.

Note: in your example, you've passed an array ([]) as a default, which is wrong. You probably meant to pass an empty object {}, but TypeScript isn't going to like that.

huangapple
  • 本文由 发表于 2023年6月19日 16:22:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76504863.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定