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

相关推荐
Martin -Tang几秒前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发1 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html