Cursor插件系统深度解析:Web Boot拓扑与plugin.json运行时契约
2026/10/4 17:08:10
React 组件的生命周期(Lifecycle)是指组件从创建到销毁的整个过程,包括挂载、更新和卸载三个主要阶段。这套机制允许开发者在组件的不同生命周期节点注入自定义逻辑,如初始化状态、请求数据、清理资源等。
关键点:
useEffect等 Hook 模拟生命周期。但本文重点讲解类组件的经典生命周期(基于 React 18+)。componentWillMount、componentWillReceiveProps、componentWillUpdate为 UNSAFE_(不推荐使用,可能在未来版本移除)。useEffect、useState等实现类似功能。下面按时间线(从挂载到卸载)详细拆解每个阶段,包括方法调用顺序、用途、代码示例和注意事项。
这一阶段从组件实例化开始,到插入 DOM 结束。顺序固定。
| 方法名称 | 调用时机 | 用途 / 常见操作 | 是否能访问 DOM | 异步渲染影响 |
|---|---|---|---|---|
| constructor() | 组件实例化时(props 传入前) | 初始化 state、绑定方法(this.xxx = this.xxx.bind(this)) | 否 | 无 |
| static getDerivedStateFromProps(props, state) | constructor 后 / render 前(静态方法) | 从 props 派生 state(很少用) | 否 | 无 |
| render() | 所有准备就绪后 | 返回 JSX / React 元素(纯函数,不能有副作用) | 否 | — |
| componentDidMount() | render 后,组件已插入 DOM | 请求数据、添加事件监听、setState(初始化后更新) | 是 | 无 |
代码示例:
class MyComponent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; this.handleClick = this.handleClick.bind(this); // 绑定方法 } static getDerivedStateFromProps(nextProps, prevState) { if (nextProps.initialCount !== prevState.count) { return { count: nextProps.initialCount }; // 从 props 更新 state } return null; } componentDidMount() { // 发起 API 请求 fetch('/api/data').then(res => this.setState({ data: res })); document.addEventListener('click', this.handleClick); // 添加全局监听 } render() { return <div>Count: {this.state.count}</div>; } }注意:
当 props/state 变化、父组件重渲染或 forceUpdate() 时触发。顺序类似挂载,但多了一些更新前检查。
| 方法名称 | 调用时机 | 用途 / 常见操作 | 是否能访问 DOM | 异步渲染影响 |
|---|---|---|---|---|
| static getDerivedStateFromProps(props, state) | props/state 变化后,render 前 | 从新 props 更新 state | 否 | 无 |
| shouldComponentUpdate(nextProps, nextState) | getDerivedStateFromProps 后 | 性能优化:返回 false 阻止渲染(PureComponent 默认实现) | 否 | 无 |
| render() | shouldComponentUpdate 返回 true 后 | 返回新 JSX | 否 | — |
| getSnapshotBeforeUpdate(prevProps, prevState) | render 后,DOM 更新前 | 捕获 DOM 状态(如滚动位置)返回给 componentDidUpdate | 是 | 无 |
| componentDidUpdate(prevProps, prevState, snapshot) | DOM 更新后 | 更新后操作(如动画、请求新数据) | 是 | 无 |
代码示例:
class MyComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { return nextProps.value !== this.props.value; // 浅比较,避免不必要渲染 } getSnapshotBeforeUpdate(prevProps, prevState) { // 捕获滚动位置 return document.getElementById('scroll-container').scrollTop; } componentDidUpdate(prevProps, prevState, snapshot) { if (this.props.value !== prevProps.value) { // 根据 snapshot 恢复滚动位置 document.getElementById('scroll-container').scrollTop = snapshot; // 或发起新请求 fetch(`/api/update?newValue=${this.props.value}`); } } render() { return <div>Value: {this.props.value}</div>; } }注意:
当组件被移除(父组件不渲染它)时触发。只有一个方法。
| 方法名称 | 调用时机 | 用途 / 常见操作 | 是否能访问 DOM | 异步渲染影响 |
|---|---|---|---|---|
| componentWillUnmount() | 组件即将从 DOM 移除前 | 清理资源:移除事件监听、取消定时器、关闭连接 | 是 | 无 |
代码示例:
class MyComponent extends React.Component { componentDidMount() { this.timer = setInterval(() => console.log('tick'), 1000); document.addEventListener('click', this.handleClick); } componentWillUnmount() { clearInterval(this.timer); // 清理定时器 document.removeEventListener('click', this.handleClick); // 移除监听 // 关闭 WebSocket 等 } render() { return <div>Unmounting Example</div>; } }注意:
类组件生命周期正逐渐被 Hooks 取代。Hooks 更简洁、复用性强。
| 类组件方法 | Hooks 等价物 | 备注 |
|---|---|---|
| constructor | useState 初始值 | — |
| getDerivedStateFromProps | useEffect + 依赖数组 | — |
| componentDidMount | useEffect(() => { … }, []) | 空依赖数组 |
| shouldComponentUpdate | React.memo / useMemo | — |
| componentDidUpdate | useEffect(() => { … }, [deps]) | 非空依赖 |
| componentWillUnmount | useEffect(() => { return cleanup; }, [deps]) | 返回清理函数 |
Hooks 示例(模拟类组件):
import { useState, useEffect } from 'react'; function MyFunctionalComponent({ value }) { const [count, setCount] = useState(0); useEffect(() => { // componentDidMount + componentDidUpdate fetch(`/api/data?value=${value}`).then(res => setCount(res.count)); return () => { // componentWillUnmount console.log('清理资源'); }; }, [value]); // 依赖 value 变化 return <div>Count: {count}</div>; }注意:useEffect 的依赖数组是关键(空数组 = 只挂载时执行;无数组 = 每次渲染都执行)。
掌握这些,你就能在 React 项目中精准控制组件行为!如果想看具体 Hooks 示例或某个方法的深度代码实战,告诉我,我们继续。