# 类组件中的 state 和生命周期方法

URL: https://caijiao.org/react/chapter5/class-component-state
Source: docs/react/chapter5/class-component-state.md
Description: 类组件中的 state 和生命周期方法是 React 中管理状态和控制组件行为的核心机制。通过 state，组件可以存储数据，而生命周期方法则允许在特定时机执行代码，如组件的挂载、更新和卸载。

在 React 类组件中，`state` 和生命周期方法是两个重要的概念。`state` 用于存储和管理组件的动态数据，而生命周期方法则在组件的不同生命周期阶段执行特定操作。

## 1. state

`state` 是 React 类组件中的一个重要特性，表示组件的内部数据。每个类组件都有一个 `state` 对象，该对象可以在组件内被修改，并且当 `state` 更新时，组件会重新渲染。

### 1.1 初始化 `state`

在类组件中，`state` 通常在构造函数中初始化：

```jsx
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };  // 初始化 state
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Increment
        </button>
      </div>
    );
  }
}
````

在上面的代码中，`state` 初始化为 `{ count: 0 }`，通过 `this.setState` 方法更新 `count`。

### 1.2 更新 `state`

在类组件中，可以通过 `this.setState()` 来更新 `state`。该方法会合并当前的 `state` 和传入的新值，并触发组件重新渲染。

```jsx
this.setState({ count: this.state.count + 1 });
```

`this.setState` 是异步的，因此在更新之后立即访问 `state` 可能无法获取到最新的值。

## 2. 生命周期方法

生命周期方法允许我们在组件的不同阶段执行代码。React 组件的生命周期分为三个主要阶段：挂载（mounting）、更新（updating）和卸载（unmounting）。不同的生命周期方法提供了不同的钩子来在这些阶段进行操作。

### 2.1 挂载阶段

在挂载阶段，组件被插入到 DOM 中，相关的生命周期方法会被调用。

* **`constructor(props)`**：在组件创建时调用，通常用于初始化 `state` 和绑定事件处理函数。
* **`componentDidMount()`**：组件挂载完成后调用，适合进行网络请求、订阅等操作。

```jsx
class App extends React.Component {
  componentDidMount() {
    console.log('Component has mounted');
  }

  render() {
    return <h1>Hello, World!</h1>;
  }
}
```

### 2.2 更新阶段

组件更新时，生命周期方法会被调用。更新阶段通常发生在 `props` 或 `state` 发生变化时。

* **`shouldComponentUpdate(nextProps, nextState)`**：决定是否应该重新渲染组件，返回布尔值。默认返回 `true`，可以通过此方法优化性能。
* **`componentDidUpdate(prevProps, prevState)`**：组件更新后调用，适合进行 DOM 操作或网络请求等副作用操作。

```jsx
class Counter extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    // 如果 count 没有变化，则不更新组件
    return nextState.count !== this.state.count;
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('Component has updated');
  }

  render() {
    return <button onClick={() => this.setState({ count: this.state.count + 1 })}>Increment</button>;
  }
}
```

### 2.3 卸载阶段

组件卸载时会调用以下生命周期方法：

* **`componentWillUnmount()`**：组件卸载前调用，通常用于清理操作，如取消订阅、清除定时器等。

```jsx
class Timer extends React.Component {
  componentDidMount() {
    this.timerID = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    console.log('Tick');
  }

  render() {
    return <div>Timer</div>;
  }
}
```

## 3. 总结

类组件的 `state` 和生命周期方法提供了对组件行为的精细控制。`state` 用于存储和更新组件的数据，而生命周期方法则允许开发者在组件的各个阶段执行操作。通过合理使用这些机制，React 开发者可以更高效地管理组件的状态和副作用。
