相信小伙伴们,在与 React 接触的过程中,useState 是最频繁使用的方法之一。
概念
什么是useState,useState 是一个 React Hook,它允许你向你的组件添加一个状态变量。
const [state, setState] = useState(initialState)
在使用时,需要注意:在组件的最顶层调用 useState 来声明一个 state variable。您不能在循环或条件中调用它。如果需要,请提取一个新组件并将 state 移动到其中。示例如下:
import { useState } from 'react';
function MyComponent() {
const [age, setAge] = useState(28);
const [name, setName] = useState('Taylor');
const [todos, setTodos] = useState(() => createTodos());
// ...
说明
State variable 的命令规则,诸如 [something, setSomething]。
参数 initialState:您希望 state variable 的最初值。它可以是任何类型的值,但函数有一种特殊的行为。如果将函数作为 initialState 传递,则它将被视为初始值设定项函数 。它应该是纯函数,不应包含任何参数,并且应返回任何类型的值。React 将在初始化组件时调用你的初始化器函数,并将其返回值存储为初始状态。
set 函数 ,允许您将其更改为任何其他值以响应交互。
调用 set 函数,不会更改已执行代码中的当前状态,它只影响从下一次渲染开始返回的 useState:
function handleClick() {
setName('Robin');
console.log(name); // Still "Taylor"!
}
假设年龄为42岁,该处理程序调用 setAge(42 + 1) 3次,如下:
function handleClick() {
setAge(age + 1); // setAge(42 + 1)
setAge(age + 1); // setAge(42 + 1)
setAge(age + 1); // setAge(42 + 1)
}
但是,当处理程序执行结果后,年龄依旧是43,这是因为 set 函数不会更改已运行代码中的 age 的状态变量。因此每个 seAge(age + 1) 调用都变成了 setAge(43)。
更新状态中的对象和数组
您可以将对象和数组放入 state 中。在 React 中,state 被认为是只读的,因此你应该替换它而不是改变现有的对象 。例如,如果你有一个 state 中的表单对象,请不要改变它:
// 🚩 Don't mutate an object in state like this:
form.firstName = 'Taylor';
相反,通过创建一个新对象来替换整个对象:
// ✅ Replace state with a new object
setForm({
...form,
firstName: 'Taylor'
});
避免重新创建初始状态
React 保存一次初始状态,并在下一次渲染时忽略它。
function TodoList() {
const [todos, setTodos] = useState(createInitialTodos());
// ...
尽管 createInitialTodos() 的结果仅用于初始渲染,但您仍然在每次渲染时调用此函数。如果创建大型数组或执行昂贵的计算,这可能会很浪费。
要解决这个问题,你可以将其作为初始化函数传递给 useState:
function TodoList() {
const [todos, setTodos] = useState(createInitialTodos);
// ...
请注意,您传递的是 createInitialTodos( 函数本身 ),而不是 createInitialTodos(),
这是调用它的结果。如果你将函数传递给 useState,React 只会在初始化期间调用它。