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 组件的生命周期。

相关推荐
web150850966412 小时前
【React&前端】大屏适配解决方案&从框架结构到实现(超详细)(附代码)
前端·react.js·前端框架
理想不理想v2 小时前
前端项目性能优化(详细)
前端·性能优化
CodeToGym2 小时前
使用 Vite 和 Redux Toolkit 创建 React 项目
前端·javascript·react.js·redux
Cachel wood3 小时前
Vue.js前端框架教程8:Vue消息提示ElMessage和ElMessageBox
linux·前端·javascript·vue.js·前端框架·ecmascript
PP东4 小时前
ES6学习Generator 函数(生成器)(八)
javascript·学习·es6
桃园码工5 小时前
4_使用 HTML5 Canvas API (3) --[HTML5 API 学习之旅]
前端·html5·canvas
桃园码工5 小时前
9_HTML5 SVG (5) --[HTML5 API 学习之旅]
前端·html5·svg
人才程序员5 小时前
QML z轴(z-order)前后层级
c语言·前端·c++·qt·软件工程·用户界面·界面
m0_548514775 小时前
前端三大主流框架:React、Vue、Angular
前端·vue.js·react.js
m0_748232396 小时前
单页面应用 (SPA):现代 Web 开发的全新视角
前端