在 React TypeScript 中键入 useState 作为对象
Type useState as an Object in React TypeScript
要useState
在 React 中将钩子键入为对象,请使用钩子的泛型,例如
const [employee, setEmployee] = useState<{name: string; salary: number}>({name: '',salary: 0})
. 状态变量将只接受指定类型的键值对。
应用程序.tsx
import {useEffect, useState} from 'react'; const App = () => { // 👇️ const employee: {name: string; salary: number;} const [employee, setEmployee] = useState<{name: string; salary: number}>({ name: '', salary: 0, }); useEffect(() => { setEmployee({name: 'James', salary: 100}); }, []); return ( <div> <h2>Name: {employee.name}</h2> <h2>Salary: {employee.salary}</h2> </div> ); }; export default App;
我们使用
泛型
来正确键入useState
钩子,同时使用对象初始化钩子。
有时您可能不想为对象的所有属性设置初始值。在这种情况下,您可以将属性标记为可选。
应用程序.tsx
import {useEffect, useState} from 'react'; const App = () => { // 👇️ mark salary as optional const [employee, setEmployee] = useState<{ name: string; salary?: number }>({ name: '', }); useEffect(() => { setEmployee({name: 'James', salary: 100}); }, []); return ( <div> <h2>Name: {employee.name}</h2> <h2>Salary: {employee.salary}</h2> </div> ); }; export default App;
我们使用问号将该salary
属性标记为
可选。
该属性可以存储一个undefined
值或一个类型的值number
。
这就是为什么我们在初始化状态对象时不需要提供它。
如果您为对象的所有属性提供初始值,TypeScript 将能够推断出状态变量的类型。
应用程序.tsx
import {useEffect, useState} from 'react'; const App = () => { // 👇️ const employee: {name: string;salary: number;} // ✅ typed correctly without a generic const [employee, setEmployee] = useState({ name: '', salary: 0, }); useEffect(() => { setEmployee({name: 'James', salary: 100}); }, []); return ( <div> <h2>Name: {employee.name}</h2> <h2>Salary: {employee.salary}</h2> </div> ); }; export default App;
我们为对象的所有属性传递了初始值,这使 TypeScript 能够employee
正确键入变量。
但是,最佳做法是始终显式键入挂钩,尤其是在处理数组和对象时。
useState
在某些情况下,您可能事先不知道要在对象上设置的所有属性。
应用程序.tsx
import {useEffect, useState} from 'react'; const App = () => { // 👇️ flexible object type const [employee, setEmployee] = useState<{[key: string]: any}>({}); useEffect(() => { setEmployee({ name: 'James', salary: 100, department: 'Dev', tasks: ['dev', 'test', 'ship'], }); }, []); return ( <div> <h2>Name: {employee.name}</h2> <h2>Salary: {employee.salary}</h2> </div> ); }; export default App;
该{[key: string]: any}
语法是 TypeScript 中的
索引签名
,当我们事先不知道类型属性的所有名称和值的形状时使用。
示例中的索引签名意味着当一个对象被索引为 a
string
时,它将返回一个any
类型的值。当您事先不知道对象的所有属性时,可以使用这种方法。
如果要将对象属性设置为多种类型之一,请使用联合。
应用程序.tsx
import {useEffect, useState} from 'react'; const App = () => { const [employee, setEmployee] = useState<{ name: string; // 👇️ string OR number salary: string | number; }>({ name: '', salary: '', }); useEffect(() => { setEmployee({name: 'James', salary: 100}); }, []); return ( <div> <h2>Name: {employee.name}</h2> <h2>Salary: {employee.salary}</h2> </div> ); }; export default App;
我们使用
联合
将salary
属性设置为string
or类型number
。
如果你的useState
钩子很忙,将你传递给泛型的类型提取到
类型别名
或
接口中。
应用程序.tsx
import {useEffect, useState} from 'react'; type Employee = { name: string; salary: number; }; const App = () => { // 👇️ const employee: {name: string; salary: number;} const [employee, setEmployee] = useState<Employee>({ name: '', salary: 0, }); useEffect(() => { setEmployee({name: 'James', salary: 100}); }, []); return ( <div> <h2>Name: {employee.name}</h2> <h2>Salary: {employee.salary}</h2> </div> ); }; export default App;
语法useState<Employee>
更容易阅读,尤其是在处理大对象时。