# useState 钩子的使用

URL: https://caijiao.org/react/chapter5/use-state
Source: docs/react/chapter5/use-state.md
Description: 'useState' 是 React 中的一个钩子函数，用于在函数组件中定义和管理状态。通过 'useState'，组件可以存储和更新数据，从而在状态变化时重新渲染组件。

`useState` 是 React 中的一个内置钩子，允许在函数组件中添加状态。它使得函数组件能够有状态管理的能力，而不需要使用类组件。`useState` 返回一个数组，其中包含当前状态的值和更新该状态的函数。

## 1. useState 的基本用法

使用 `useState` 的基本语法如下：

```jsx
const [state, setState] = useState(initialState);
````

* `state` 是当前的状态值。
* `setState` 是用于更新状态的函数。
* `initialState` 是状态的初始值。

### 示例：

```jsx
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

export default Counter;
```

在这个例子中，`useState(0)` 初始化了 `count` 状态为 `0`。每次点击按钮时，`setCount(count + 1)` 更新 `count` 的值，组件会重新渲染，显示最新的 `count` 值。

## 2. 初始值

`useState` 的参数 `initialState` 可以是任意类型的值，甚至是一个函数。它也可以是一个对象、数组或更复杂的数据结构。

### 示例：初始值为对象

```jsx
import React, { useState } from 'react';

function UserProfile() {
  const [user, setUser] = useState({ name: 'Alice', age: 30 });

  return (
    <div>
      <p>Name: {user.name}</p>
      <p>Age: {user.age}</p>
      <button onClick={() => setUser({ ...user, age: user.age + 1 })}>Increase Age</button>
    </div>
  );
}

export default UserProfile;
```

在上面的例子中，`user` 是一个对象，初始值为 `{ name: 'Alice', age: 30 }`。每次点击按钮时，`setUser` 更新 `age` 的值，并触发组件重新渲染。

## 3. 更新状态时的注意事项

### 3.1 直接更新状态值

状态更新函数会将新的状态值直接赋给当前状态。对于基本数据类型（如数字、字符串等），`setState` 会直接替换原来的状态值。

### 3.2 使用回调更新状态

如果更新依赖于先前的状态值，建议使用回调函数。回调函数接收当前的状态值，并返回新的状态值。

```jsx
setCount(prevCount => prevCount + 1);
```

这种方式确保在多个状态更新时能正确地获取到最新的状态值。

### 3.3 状态合并

对于对象或数组等复杂数据类型，`useState` 不会自动合并旧的状态与新的状态。需要手动合并状态。

```jsx
setUser(prevUser => ({ ...prevUser, name: 'Bob' }));
```

在这个例子中，通过展开运算符（`...`）将旧的 `user` 对象与新的 `name` 合并，从而保持其它属性不变。

## 4. 延迟初始化

`useState` 允许延迟计算初始状态，特别是当计算初始值较为复杂时。可以将一个函数作为 `useState` 的参数，这个函数将只在组件首次渲染时执行一次。

```jsx
const [count, setCount] = useState(() => expensiveComputation());
```

在此例中，`expensiveComputation` 只有在组件首次渲染时才会执行。

## 5. 绑定事件与状态更新

`useState` 通常与事件处理函数一起使用，例如在按钮点击时更新状态：

```jsx
function App() {
  const [text, setText] = useState("");

  const handleChange = (e) => {
    setText(e.target.value);
  };

  return (
    <div>
      <input type="text" value={text} onChange={handleChange} />
      <p>{text}</p>
    </div>
  );
}
```

在这个例子中，`text` 状态与输入框的值绑定，每次输入框的值改变时，`handleChange` 会更新 `text`，从而导致组件重新渲染。

## 6. 总结

`useState` 是 React 中处理状态的基础工具，使得函数组件能够拥有与类组件相同的状态管理能力。通过理解和正确使用 `useState`，开发者可以方便地管理 UI 状态并确保应用的交互性。
