react有哪些生命周期
React生命周期详解
类组件生命周期
1️⃣ 挂载阶段 (Mounting)
class MyComponent extends React.Component {// 1. 构造函数constructor(props) {super(props);this.state = { count: 0 };console.log('1. constructor');}// 2. 从props获取statestatic getDerivedStateFromProps(props, state) {console.log('2. getDerivedStateFromProps');return null; // 返回null表示不更新state}// 3. 渲染组件render() {console.log('3. render');return <div>{this.state.count}</div>;}// 4. 组件已挂载componentDidMount() {console.log('4. componentDidMount');// 适合发送网络请求、添加订阅}
}
2️⃣ 更新阶段 (Updating)
class MyComponent extends React.Component {// 1. 从props获取statestatic getDerivedStateFromProps(props, state) {console.log('1. getDerivedStateFromProps (更新)');return null;}// 2. 是否应该更新shouldComponentUpdate(nextProps, nextState) {console.log('2. shouldComponentUpdate');return true; // 返回false可阻止更新}// 3. 渲染组件render() {console.log('3. render (更新)');return <div>{this.state.count}</div>;}// 4. 获取更新前的快照getSnapshotBeforeUpdate(prevProps, prevState) {console.log('4. getSnapshotBeforeUpdate');return { scrollPosition: 100 }; // 传递给componentDidUpdate}// 5. 组件已更新componentDidUpdate(prevProps, prevState, snapshot) {console.log('5. componentDidUpdate', snapshot);// 可以在这里操作DOM,发送网络请求(注意避免无限循环)}
}
3️⃣ 卸载阶段 (Unmounting)
class MyComponent extends React.Component {// 组件即将卸载componentWillUnmount() {console.log('componentWillUnmount');// 清理订阅、定时器等资源}
}
4️⃣ 错误处理 (Error Handling)
class ErrorBoundary extends React.Component {constructor(props) {super(props);this.state = { hasError: false };}// 捕获子组件错误static getDerivedStateFromError(error) {// 更新state使下一次渲染显示错误UIreturn { hasError: true };}// 记录错误信息componentDidCatch(error, info) {console.error('组件错误:', error, info);// 可以发送错误到服务器}render() {if (this.state.hasError) {return <h1>出错了!</h1>;}return this.props.children;}
}
函数组件中的生命周期等价物
import React, { useState, useEffect, useRef } from 'react';function FunctionalComponent(props) {// 替代 constructor 中的 state 初始化const [count, setCount] = useState(0);// 类似 componentDidMountuseEffect(() => {console.log('组件已挂载');// 类似 componentWillUnmountreturn () => {console.log('组件将卸载');};}, []); // 空依赖数组表示仅在挂载和卸载时执行// 类似 componentDidUpdate (特定属性)useEffect(() => {console.log('count已更新:', count);}, [count]); // 依赖count变化时执行// 获取上一次的props或state (类似 getSnapshotBeforeUpdate)const prevCountRef = useRef();useEffect(() => {prevCountRef.current = count;});const prevCount = prevCountRef.current;console.log('render等价物 - 函数组件每次渲染都会执行'); return (<div><p>当前计数: {count}</p><p>上一次计数: {prevCount}</p><button onClick={() => setCount(count + 1)}>增加</button></div>);
}// 类似 shouldComponentUpdate
const MemoizedComponent = React.memo(FunctionalComponent);
生命周期执行顺序
首次渲染
- constructor()
- static getDerivedStateFromProps()
- render()
- componentDidMount()
更新过程
- static getDerivedStateFromProps()
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
卸载过程
- componentWillUnmount()
已弃用的生命周期方法
以下方法在React 17中已被移除:
componentWillMount()componentWillReceiveProps()componentWillUpdate()
这些方法容易被误用,并且在React的异步渲染模式下可能导致问题。
常见生命周期使用场景
生命周期方法 | 适用场景 |
---|---|
constructor | 初始化state、绑定方法 |
componentDidMount | 发送网络请求、添加DOM事件监听、初始化第三方库 |
componentDidUpdate | 响应props/state变化、DOM操作、有条件的网络请求 |
componentWillUnmount | 清理定时器、取消网络请求、移除事件监听 |
shouldComponentUpdate | 性能优化、阻止不必要的渲染 |
getDerivedStateFromProps | 根据props更新state(罕用) |
getSnapshotBeforeUpdate | 在DOM更新前捕获信息(如滚动位置) |
函数组件Hooks与类生命周期对应关系
// 类比对照表
constructor, componentDidMount -> useEffect(()=>{}, [])
componentDidUpdate -> useEffect(()=>{}, [依赖])
componentWillUnmount -> useEffect(()=>{ return ()=>{} }, [])
shouldComponentUpdate -> React.memo + useCallback/useMemo