React.js实战之React 生命周期

简介: ReactJS 的核心思想是组件化,即按功能封装成一个一个的组件,各个组件维护自己的状态和 UI,当状态发生变化时,会自定重新渲染整个组件,多个组件一起协作共同构成了 ReactJS 应用。

ReactJS 的核心思想是组件化,即按功能封装成一个一个的组件,各个组件维护自己的状态和 UI,当状态发生变化时,会自定重新渲染整个组件,多个组件一起协作共同构成了 ReactJS 应用。

为了能够更好的创建和使用组件,我们首先要了解组件的生命周期。
生命周期


img_6246573d522a109a4ce8aad58b508143.png

img_228b9158a4fe825c2a4bf583a7af6d2b.png

1 组件的生命周期

创建阶段、实例化阶段、更新阶段、销毁阶段。
下面对各个阶段分别进行介绍。

1.1加载阶段

img_8dbf82f94bf9f2f801e34e35c253f26c.png
  • 该阶段主要发生在创建组件类的时候,即调用 React.createClass 时触发
  • 这个阶段只会触发一个 getDefaultProps 方法,该方法会返回一个对象并缓存。然后与父组件指定的 props 对象合并,最后赋值给 this.props 作为该组件的默认属性。

1.2 实例化阶段

该阶段主要发生在实例化组件类的时候,也就是该组件类被调用的时候触发。
这个阶段会触发一系列的流程,按执行顺序如下
(1)getInitialState:初始化组件的 state 的值。其返回值会赋值给组件的 this.state 属性。
(2)componentWillMount:根据业务逻辑来对 state 进行相应的操作。
(3)render:根据 state 的值,生成页面需要的虚拟 DOM 结构,并返回该结构。
(4)componentDidMount:对根据虚拟 DOM 结构而生的真实 DOM 进行相应的处理。组件内部可以通过 ReactDOM.findDOMNode(this) 来获取当前组件的节点,然后就可以像 Web 开发中那样操作里面的 DOM 元素了。

1.3 更新阶段

img_08cdb2239c06587e2edbb7d22db159ce.png

这主要发生在用户操作之后或者父组件有更新的时候,此时会根据用户的操作行为进行相应得页面结构的调整。这个阶段也会触发一系列的流程,按执行顺序如下:
(1)componentWillReceiveProps:当组件接收到新的 props 时,会触发该函数。在改函数中,通常可以调用 this.setState 方法来完成对 state 的修改。
(2)shouldComponentUpdate:该方法用来拦截新的 props 或 state,然后根据事先设定好的判断逻辑,做出最后要不要更新组件的决定。
(3)componentWillUpdate:当上面的方法拦截返回 true 的时候,就可以在该方法中做一些更新之前的操作。
(4)render:根据一系列的 diff 算法,生成需要更新的虚拟 DOM 数据。(注意:在 render 中最好只做数据和模板的组合,不应进行 state 等逻辑的修改,这样组件结构更加清晰)
(5)componentDidUpdate:该方法在组件的更新已经同步到 DOM 中去后触发,我们常在该方法中做一 DOM 操作。


img_4061bf527caed7f8413569a9b3ff90e0.png

1.4 销毁阶段

img_79019a85fa3395df7acf694fe4cd114e.png

这个阶段只会触发一个叫 componentWillUnmount 的方法。
当组件需要从 DOM 中移除的时候,我们通常会做一些取消事件绑定、移除虚拟 DOM 中对应的组件数据结构、销毁一些无效的定时器等工作。这些事情都可以在这个方法中处理。


img_db1b0f65f4083ced54805183742b919c.png
import React from 'react';
import ReactDOM from 'react-dom';


class Component extends React.Component{
    // 构造函数
    constructor(props){
        super(props)
        this.state = {
            data: 'Old State'
        }
        console.log('初始化数据','constructor');
    }
    // 组件将要加载
    componentWillMount(){
        console.log('componentWillMount');
    }
    // 组件加载完成
    componentDidMount(){
        console.log('componentDidMount');
    }
    // 将要接收父组件传来的props
    componentWillReceiveProps(){
        console.log('componentWillReceiveProps');
    }
    // 子组件是不是应该更新
    shouldComponentUpdate(){
        console.log('shouldComponentUpdate');
        return true;
    }
    // 组件将要更新
    componentWillUpdate(){
        console.log('componentWillUpdate');
    }
    // 组件更新完成
    componentDidUpdate(){
        console.log('componentDidUpdate');
    }
    // 组件即将销毁
    componentWillUnmount(){
        console.log('componentWillUnmount');
    }
    // 处理点击事件
    handleClick(){
        console.log('更新数据:');
        this.setState({
            data: 'New State'
        });
    }
    // 渲染
    render(){
        console.log('render')
        return (
            <div>
                <div>Props: {this.props.data}</div>
                <button onClick={()=>{this.handleClick()}}>更新组件</button>
            </div>
        );
    }
}

class App extends React.Component{
    // 构造函数
    constructor(props){
        super(props)
        this.state = {
            data: 'Old Props',
            hasChild: true
        }
        console.log('初始化数据','constructor');
    }
    onPropsChange(){
        console.log('更新props:');
        this.setState({
            data: 'New Props'
        });
    }
    onDestoryChild(){
        console.log('干掉子组件:');
        this.setState({
            hasChild: false
        });
    }
    render(){
        return (
            <div>
                {
                    this.state.hasChild ? <Component data={this.state.data}/> : null
                }
                <button onClick={()=>{this.onPropsChange()}}>改变Props</button>
                <button onClick={()=>{this.onDestoryChild()}}>干掉子组件</button>
            </div>
        );
    }
}

ReactDOM.render(
    <App/>,
    document.getElementById('app')
);
目录
相关文章
|
8月前
|
前端开发 API 数据库
React Server Components 实战:解锁高效渲染新姿势
React Server Components 实战:解锁高效渲染新姿势
315 81
|
9月前
|
缓存 前端开发 安全
解锁下一代 React:Server Components 实战指南
解锁下一代 React:Server Components 实战指南
283 84
|
9月前
|
前端开发
React Hooks数据获取:避免内存泄漏的实战指南
React Hooks数据获取:避免内存泄漏的实战指南
|
10月前
|
人工智能 自然语言处理 JavaScript
通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
通义灵码基于自然语言需求,快速生成完整Vue组件。例如,用Vue 2和JavaScript实现贪吃蛇游戏:包含键盘控制、得分系统、游戏结束判定与Canvas动态渲染。AI生成的代码符合规范,支持响应式数据与事件监听,还能进阶优化(如增加启停按钮、速度随分数提升)。传统需1小时的工作量,使用通义灵码仅10分钟完成,大幅提升开发效率。操作简单:安装插件、输入需求、运行项目即可实现功能。
479 4
 通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
|
6月前
|
编解码 前端开发 JavaScript
js react antd 实现页面低分变率和高分变率下字体大小自适用,主要是配置antd
在React中结合Ant Design与媒体查询,通过less变量和响应式断点动态调整`@font-size-base`,实现多分辨率下字体自适应,提升跨设备体验。
282 2
|
7月前
|
人工智能 自然语言处理 前端开发
让AI学会"边做边想":ReAct的实战指南
还在为AI的「知其然不知其所以然」而烦恼?ReAct技术让AI不仅会思考,更会行动!通过模拟人类的思考-行动-观察循环,让AI从书呆子变身为真正的问题解决专家。几行代码就能构建智能Agent,告别AI幻觉,拥抱可追溯的推理过程!
604 7
|
6月前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
8月前
|
JavaScript 前端开发 算法
流量分发代码实战|学会用JS控制用户访问路径
流量分发工具(Traffic Distributor),又称跳转器或负载均衡器,可通过JavaScript按预设规则将用户随机引导至不同网站,适用于SEO优化、广告投放、A/B测试等场景。本文分享一段不到百行的JS代码,实现智能、隐蔽的流量控制,并附完整示例与算法解析。
218 1
|
11月前
|
前端开发 JavaScript NoSQL
使用 Node.js、Express 和 React 构建强大的 API
本文详细介绍如何使用 Node.js、Express 和 React 构建强大且动态的 API。从开发环境搭建到集成 React 前端,再到利用 APIPost 高效测试 API,适合各水平开发者。内容涵盖 Node.js 运行时、Express 框架与 React 库的基础知识及协同工作方式,还涉及数据库连接和前后端数据交互。通过实际代码示例,助你快速上手并优化应用性能。
|
12月前
|
前端开发 数据可视化 测试技术
React音频播放列表组件开发实战:常见问题与避坑指南
本文介绍了构建React音频播放列表组件的核心架构与常见问题解决方案。通过管理播放状态、列表索引和音频进度,结合异步控制、状态清理、节流优化等技术,确保流畅的用户体验。针对移动端兼容性、内存泄漏、列表渲染性能等问题提供了具体修复方案,并分享了自定义Hook封装、可视化音频波形等进阶实践。最后,总结了性能优化法则和测试关键点,帮助开发者打造生产级可靠的音频播放组件。
334 18