React生命周期案例详解

React 组件的生命周期是指组件从创建、渲染、更新到卸载的整个过程。在 React 16 及之前的版本中,生命周期方法被分为几个不同的阶段:挂载(Mounting)、更新(Updating)、卸载(Unmounting)以及错误处理(Error Handling,React 16 引入)。但从 React 17 开始,一些生命周期方法被标记为不推荐使用(如 componentWillMount、componentWillReceiveProps、componentWillUpdate),并引入了新的钩子函数 getDerivedStateFromProps 和 componentDidMount(实际上 componentDidMount 在更早的版本就已存在,但这里强调其作为替代某些旧生命周期方法的作用)。在 React 18 中,又引入了新的并发特性,这可能会进一步影响生命周期的概念,但本文主要基于 React 16.x 和 17.x 进行讲解。

挂载(Mounting)

这是组件被插入到 DOM 中的过程。

constructor(props)

类组件的构造函数,初始化 state 或绑定事件处理函数时调用。

jsx

class MyComponent extends React.Component {

constructor(props) {

super(props);

this.state = {

count: 0

};

}

}

static getDerivedStateFromProps(props, state)

当组件实例化后和接收新的 props 时将被调用。它应返回一个对象来更新 state,或者返回 null 来表明新的 props 不需要更新任何 state。

jsx

class MyComponent extends React.Component {

static getDerivedStateFromProps(props, state) {

if (props.count !== state.count) {

return { count: props.count };

}

return null;

}

}

render()

必须的方法,当组件需要更新时被调用,返回组件要渲染的内容。

jsx

class MyComponent extends React.Component {

render() {

return <div>{this.state.count}</div>;

}

}

componentDidMount()

组件挂载到 DOM 之后调用。此时可以进行 API 调用、订阅等操作。

jsx

class MyComponent extends React.Component {

componentDidMount() {

// 执行 API 调用等

}

}

更新(Updating)

组件的 props 或 state 发生变化时会进入更新过程。

static getDerivedStateFromProps(props, state)

组件更新时被调用,用于根据新的 props 来设置 state。

shouldComponentUpdate(nextProps, nextState)

决定组件是否应该更新。默认返回 true。返回 false 会阻止更新。

jsx

class MyComponent extends React.Component {

shouldComponentUpdate(nextProps, nextState) {

if (nextProps.count === this.props.count) {

return false;

}

return true;

}

}

render()

更新后,重新渲染组件。

getSnapshotBeforeUpdate(prevProps, prevState)

真实的 DOM 更新前调用。返回的值作为 componentDidUpdate 的第三个参数。

jsx

class MyComponent extends React.Component {

getSnapshotBeforeUpdate(prevProps, prevState) {

// 例如,记录滚动位置等

return null;

}

}

componentDidUpdate(prevProps, prevState, snapshot)

更新后立即调用。可以在这执行 DOM 操作或者执行更多的更新操作。

jsx

class MyComponent extends React.Component {

componentDidUpdate(prevProps, prevState, snapshot) {

// 例如,处理 DOM 更新后的逻辑

}

}

卸载(Unmounting)

componentWillUnmount()

组件卸载和销毁之前调用。用于执行必要的清理操作,如取消网络请求、移除订阅等。

jsx

class MyComponent extends React.Component {

componentWillUnmount() {

// 清理操作

}

}

错误处理(Error Handling)

React 16 引入了错误边界的概念,可用以下生命周期方法捕获子组件树的 JavaScript 错误。

static getDerivedStateFromError(error)

当子组件树中有组件抛出错误后,这个生命周期方法会被调用,返回值将作为 state。

componentDidCatch(error, info)

该生命周期方法会在后代组件抛出错误后被调用,可以用来记录错误信息。

错误边界组件示例:

jsx

class ErrorBoundary extends React.Component {

constructor(props) {

super(props);

this.state = { hasError: false };

}

static getDerivedStateFromError(error) {

return { hasError: true };

}

componentDidCatch(error, info) {

// 可以将错误日志上报给你的服务器

console.log(error, info);

}

render() {

if (this.state.hasError) {

return <h1>Something went wrong.</h1>;

}

return this.props.children;

}

}

使用错误边界:

jsx

<ErrorBoundary>

<MyComponent />

</ErrorBoundary>

使用函数组件和 Hooks

在函数组件中,你可以使用 React Hooks 来模拟类组件中的生命周期方法。

useEffect 可以模拟 componentDidMount、componentDidUpdate 和 componentWillUnmount。

useState 和 useReducer 可以初始化 state,类似于 constructor。

useMemo 和 useCallback 可以优化性能,类似于 shouldComponentUpdate 的某些用例。

示例:

jsx

import React, { useState, useEffect } from 'react';

function MyComponent() {

const [count, setCount] = useState(0);

useEffect(() => {

// 类似于 componentDidMount 和 componentDidUpdate

document.title = `You clicked ${count} times`;

// 类似于 componentWillUnmount

return () => {

// 清理操作

};

}, [count]); // 依赖项数组,类似于 shouldComponentUpdate

return (

<div>

<p>You clicked {count} times</p>

<button onClick={() => setCount(count + 1)}>

Click me

</button>

</div>

);

}

以上是 React 生命周期的详细解释以及各个阶段对应的代码示例。希望这能帮助你更好地理解 React 组件的生命周期。

相关推荐
沉默璇年15 分钟前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder21 分钟前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_8827275731 分钟前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
会发光的猪。1 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
天下代码客1 小时前
【vue】vue中.sync修饰符如何使用--详细代码对比
前端·javascript·vue.js
猫爪笔记1 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
前端李易安2 小时前
Webpack 热更新(HMR)详解:原理与实现
前端·webpack·node.js
红绿鲤鱼2 小时前
React-自定义Hook与逻辑共享
前端·react.js·前端框架
Domain-zhuo2 小时前
什么是JavaScript原型链?
开发语言·前端·javascript·jvm·ecmascript·原型模式
小丁爱养花2 小时前
前端三剑客(三):JavaScript
开发语言·前端·javascript