React 扩展

文章目录

  • PureComponent
    • 1. 使用 React.Component,不会进行浅比较
    • 2. 使用 shouldComponentUpdate 生命周期钩子,手动比较
    • 3. 使用 React.PureComponent,自动进行浅比较
  • Render Props
    • 1. 使用 Children props(通过组件标签体传入结构)
    • 2. 使用 Render Props(通过组件标签属性传入结构)

PureComponent

PureComponent 在其内部实现了 shouldComponentUpdate() 方法的浅比较逻辑。当组件的 props 或 state 发生变化时,React 会通过这个方法检查前后的 props 和 state 是否相等。

如果 shouldComponentUpdate() 返回 false,则 React 不会触发组件的重新渲染过程,这可以避免不必要的渲染和可能带来的性能开销。

1. 使用 React.Component,不会进行浅比较

当执行this.setState({})时:

  • <Parent />组件 中 state 没有发生变化,也会重新执行render()
  • <Child />组件 没有接收任何props,也会重新执行render()
    .

不管父子组件的 props 或 state 有没有发生变化,都会重新执行各自的render(),重新渲染组件。这显然不符合逻辑,效率低下

import React, { Component } from 'react'

export default class Parent extends Component {

    state = { name: '张三' }

    changeName = () => {
        this.setState({})
    }

    render () {
        console.log('Parent render');
        return (
            <div>
                <button onClick={this.changeName}>点击</button>
                <Child />
            </div>
        )
    }
}


class Child extends Component {
    render () {
        console.log('Child render');
        return (
            <div>
                Child
            </div>
        )
    }
}

.

2. 使用 shouldComponentUpdate 生命周期钩子,手动比较

使用 shouldComponentUpdate 生命周期钩子,手动判断 props 或 state 的发生变化:

  • 如果父组件数据没有更新,则父组件和子组件都不需要重新render():父组件 => shouldComponentUpdate () { return false }
  • 如果父组件数据有更新,则父组件需要重新render():父组件 => shouldComponentUpdate () { return true }
  • 子组件则判断props数据有没有更新:子组件 => shouldComponentUpdate (nextProps, nextState) { return !this.props.name === nextProps.name }
import React, { Component, PureComponent } from 'react'

export default class Parent extends Component {

    state = { name: '张三' }

    changeName = () => {
        this.setState({})
    }

    shouldComponentUpdate (nextProps, nextState) {
    	// 当执行 this.setState({})时,state中数据没有变化时, return false 阻止更新.这样就不会重新渲染Parent组件,Child组件也不会更新
    	// 当执行 this.setState({ name: '李四' })时,state中数据发生改变, return true 这会重新渲染Parent组件,这是Child组件的props会改变
        if (this.state.name === nextState.name) {
            return false
        } else {
            return true
        }
    }

    render () {
        console.log('Parent render');
        return (
            <div>
                <button onClick={this.changeName}>点击</button>
                <Child name={this.state.name} />
            </div>
        )
    }
}


class Child extends Component {
	
	// 如果接收到的props中数据没有变化,则return false,阻止组件更新
    shouldComponentUpdate (nextProps, nextState) {
        if (this.props.name === nextProps.name) {
            return false
        } else {
            return true
        }
    }

    render () {
        console.log('Child render');
        return (
            <div>
                Child
                {this.props.name}
            </div>
        )
    }
}

3. 使用 React.PureComponent,自动进行浅比较

PureComponent 在其内部实现了 shouldComponentUpdate() 方法的浅比较逻辑。当组件的 props 或 state 发生变化时,React 会通过这个方法检查前后的 props 和 state 是否相等。

import React, { PureComponent } from 'react'

export default class Parent extends PureComponent {

    state = { name: '张三' }

    changeName = () => {
        this.setState({})
    }

	// 相当于PureComponent中内置shouldComponentUpdate的判断逻辑
    // shouldComponentUpdate (nextProps, nextState) {
    //     return !this.state.name === nextState.name
    // }

    render () {
        console.log('Parent render');
        return (
            <div>
                <button onClick={this.changeName}>点击</button>
                <Child name={this.state.name} />
            </div>
        )
    }
}


class Child extends PureComponent {

	// 相当于PureComponent中内置shouldComponentUpdate的判断逻辑
    // shouldComponentUpdate (nextProps, nextState) {
    //     return !this.props.name === nextProps.name
    // }

    render () {
        console.log('Child render');
        return (
            <div>
                Child
                {this.props.name}
            </div>
        )
    }
}


Render Props

在React中,并没有直接对应于 Vue.js 中的 “插槽”(slot)的概念。Vue.js的插槽允许你在子组件的模板中预留一些占位符,这些占位符可以由父组件来填充内容。

然而,React通过其组合和props传递的特性,提供了类似的功能,但实现方式略有不同。

1. 使用 Children props(通过组件标签体传入结构)

在子组件中可以通过 this.props.children 接收并渲染父组件传递的任何内容

import React, { Component } from 'react'

export default class Parent extends Component {

    state = { name: '张三' }

    render () {
        return (
            <Child>
                <p>这是一段文本。</p>
                <button>这是一个按钮。</button>
            </Child>
        )
    }
}


class Child extends Component {
    render () {
        return (
            <div className='childNode'>
                {/* 获取到<Child>中的标签属性 */}
                {this.props.children} // 这里可以接收并渲染父组件传递的任何内容
            </div>
        )
    }
}

<Child> 内部的两个节点插入到 .childNode

在这里插入图片描述

多层嵌套

  • 通过 <Child> <Grand/> </Child> 的形式,形成父子组件

  • 通过{this.props.children}的形式,渲染内容

import React, { Component } from 'react'

// 父组件  
export default class Parent extends Component {

    state = { name: '张三' }

    render () {
        return (
            <Child>
            	{/* Grand是Child的子组件 */}
                <Grand name={this.state.name} />
            </Child>
        )
    }
}

// 子组件  
class Child extends Component {

	state = { name: '李四' }

    render () {
        return (
            <div className='childNode'>
                <p>Child组件</p>
                {this.props.children}
            </div>
        )
    }
}

// 孙子组件  
class Grand extends Component {
    render () {
        return (
            <div className='grandNode'>
                <p>Grand组件</p>
                <p>{this.props.name}</p>
            </div>
        )
    }
}

但这样 Child 组件里的数据(state = { name: '李四' })无法传递给 Grand 组件,因此需要使用 Render Props

.

2. 使用 Render Props(通过组件标签属性传入结构)

Render props是一种在React组件之间共享代码的模式。一个组件接收一个返回React元素的函数作为prop,并在其渲染方法中调用该函数。这使得父组件能够动态地决定子组件应该渲染什么内容。

  • 通过 <Child render={() => <Grand />} /> 的形式,形成父子组件:render prop 的模式来在 Child 组件中动态渲染 Grand 组件

  • 通过{this.props.render()}的形式,动态渲染内容

import React, { Component } from 'react'

// 父组件  
export default class Parent extends Component {

    state = { name: '张三' }

    render () {
        return (
        	// 通过 render prop 的模式来在 Child 组件中动态渲染 Grand 组件
            <Child render={(name) => <Grand name={name} />} />
        )
    }
}

// 子组件  
class Child extends Component {

    state = { name: '李四' }

    render () {
        return (
            <div className='childNode'>
                <p>Child组件</p>
                
				{/* <Grand>组件被放置在这里,并传入Child组件的数据(name: '李四') */}
				{/* 相当与vue中<slot>插槽,动态渲染的位置 */}
                {this.props.render(this.state.name)}  
            </div>
        )
    }
}

// 孙子组件  
class Grand extends Component {
    render () {
        return (
            <div className='grandNode'>
                <p>Grand组件</p>
                <p>{this.props.name}</p>
            </div>
        )
    }
}

这样 Child 组件里的数据(state = { name: '李四' })就可以传递给 Grand 组件
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/739693.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker-compose离线安装harbor

1、下载harbor goharbor下载&#xff1a;Releases goharbor/harbor GitHub harbor-offline-installer-v2.11.0.tgz 2、解压 tar -xvf harbor-offline-installer-v2.11.0.tgz 3、创建一个卷目录&#xff0c;并复制一份配置文件 cd harbor; mkdir data;cp harbor.yml.tmp…

Kotlin设计模式:享元模式(Flyweight Pattern)

Kotlin设计模式&#xff1a;享元模式&#xff08;Flyweight Pattern&#xff09; 在移动应用开发中&#xff0c;内存和CPU资源是非常宝贵的。享元模式&#xff08;Flyweight Pattern&#xff09;是一种设计模式&#xff0c;旨在通过对象重用来优化内存使用和性能。本文将深入探…

操作系统真象还原:用户进程

第11章-用户进程 这是一个网站有所有小节的代码实现&#xff0c;同时也包含了Bochs等文件 11.1 为什么要有任务状态TSS Linux 任务切换未采用 Intel 的做法&#xff0c;而是用了一套自己的方法&#xff0c;只是用了 TSS 的一小部分功能。 操作系统最直接控制的就是 CPU&…

解析 flink sql 转化成flink job

文章目录 背景流程flink实例实现细节定义的规则定义的物理算子定义的flink exec node 背景 在很多计算引擎里&#xff0c;都会把sql 这种标准语言&#xff0c;转成计算引擎下底层实际的算子&#xff0c;因此理解此转换的流程对于理解整个过程非常重要 流程 flink实例 public…

日常饮水中的风险来自哪里?

一杯透明、澄澈的饮用水 是你一天工作、学习和生活的动力源泉 但在你准备饮用时 如何确定水中就没有致病菌呢 联合国报告 世界上有26%的人喝不到干净卫生的饮用水1 为什么&#xff1f; 卫生设施缺乏 环保意识差 对水资源的保护不足 ... 这些因素叠加造成了饮用水的污…

Debian12中搭建TiddlyWiki服务并进行配置

一、Node.js 环境安装 apt update & apt install nodejs npm ## 查看版本 node -v npm -v二、安装Tiddlywiki npm install -g tiddlywiki## 查看版本号 tiddlywiki --version 三、配置并运行 tiddlywiki ## 在/home 目录自动创建Testwiki文件夹&#xff0c;作为wiki的存…

福昕PDF编辑器(Foxit PDF Editor)修改成中文显示

双击打开Foxit PDF Editor 点击File->Preferences 从左侧下拉菜单找到Languages选项点击&#xff0c;然后在右边选择Chinese-Simplfied&#xff08;简体中文&#xff09;&#xff0c;点击OK 点击下面的Restart Now立刻重启Foxit PDF Editor软件 重启后&#xff0c;发现软件已…

Charles 显示内存不足解决方法

弹窗出现&#xff1a;Charles is running low on memory. Recording has been stopped. Please clear the session to free memory and continue recording. 官网解决方法&#xff1a; Charles runs out of memory After recording for a while Charles will run low on ava…

国内顶级汽车制造厂的创新实践:如何利用实时数据湖为更多业务提供新鲜数据?

使用 TapData&#xff0c;化繁为简&#xff0c;摆脱手动搭建、维护数据管道的诸多烦扰&#xff0c;轻量代替 OGG、DSG 等同步工具&#xff0c;「CDC 流处理 数据集成」组合拳&#xff0c;加速仓内数据流转&#xff0c;帮助企业将真正具有业务价值的数据作用到实处&#xff0c…

CodeFuse 开源官网上线啦~

Hello ! 这里是 CodeFuse ~ CodeFuse 的使命是开发专门设计用于支持整个软件开发生命周期的大型代码语言模型&#xff08;Code LLMs&#xff09;&#xff0c;涵盖设计、需求、编码、测试、部署、运维等关键阶段。我们致力于打造创新的解决方案&#xff0c;让软件开发者们在研发…

MacOS 中 Agent 图标删除

这个是战网没有完全卸载赶紧导致的 在访达中点击前往文件夹&#xff0c;输入&#xff1a; /Users/Shared将对应的目录删掉即可。会提示需要输入密码。

Swift Combine — Debounce和Throttle的理解与使用

Debounce 和 Throttle 是两种常用的操作符&#xff0c;用于控制数据流的频率和处理延迟。但它们的实现方式略有不同。理解这些差异对于在Combine代码中做出正确选择至关重要。 Debounce Debounce 操作符用于限制数据流的频率&#xff0c;只有在指定的时间间隔内没有新数据到达…

Information security in DLMS/COSEM(Green-Book)—认证机制

Information security in DLMS/COSEM 9.2.1 概述9.2.2 DLMS/COSEM安全概念9.2.2.1 概述 9.2.2.1 概述9.2.2.2 身份识别和认证9.2.2.2.1 身份识别9.2.2.2.2 认证机制9.2.2.2.2.1 概述 无安全认证&#xff08;Lowest Level Security&#xff09;&#xff1a;低级别安全认证&#…

Vue3 + Element-plus + TS —— 动态表格自由编辑

前期回顾 《 穿越时空的代码、在回首&#xff1a;Evil.js两年后的全新解读 》-CSDN博客 Vue3 TS Element-Plus 封装Tree组件 《亲测可用》_ https://blog.csdn.net/m0_57904695/article/details/131664157?spm1001.2014.3001.5501 态表格 自由编辑 目录 ♻️ 效果图…

IS022000与HACCP:提升食品安全管理的完美结合

国际标准化组织&#xff08;ISO&#xff09;于2005年9月发布了IS022000:2005标准&#xff0c;这是一项针对食品安全管理体系的国际标准。我国以等同采用的方式制定了国家标准GB/T 22000-2006《食品安全管理体系食品链中各类组织的要求》&#xff08;以下简称“GB/T22000”&…

Docker搭建yolov8并训练、验证、推理化学仪器数据集

目录 1、安装docker 2、创建yolov8镜像 3、下载代码包 4、下载模型预训练权重 5、制作数据集 6、训练、验证及推理 &#xff08;1&#xff09;训练 &#xff08;2&#xff09;验证 &#xff08;3&#xff09;推理 中文标签显示问题 本文通过docker的方式搭建yolov8运…

C语言入门课程学习笔记10:结构体联合体位域

C语言入门课程学习笔记10 第48课 - 自定义数据类型&#xff08;上&#xff09;实验-typedef实验小结 第49课 - 自定义数据类型&#xff08;中&#xff09;实验实验小结 第50课 - 自定义数据类型&#xff08;下&#xff09;实验实验小结 第51课 - 多文件程序设计实验实验实验小结…

python项目加密和增加时间许可证

1.bat&#xff0c;执行如下的命令&#xff0c;第一句是更新或增加许可证 第二句是加密draw_face.py python offer.py pyarmor obfuscate -O dist draw_face.py绘制自制人脸.py&#xff0c;调用加密的代码draw_face代码 import sys import os import cv2# 添加加密模块所在的路…

[MYSQL] 数据库基础

1.什么是数据库 从数据库的名字可以看出,它是用来操作(增删查改....)数据的,事实上也的确如此,通过数据库,我们可以更方便.更高效的来操作.管理数据 以文件形式存储数据的缺点 文件的安全问题文件不利于数据的查询和删除文件不利于存储海量数据操作文件并不方便 为了解决上述问…

煤矿运输新篇章:数字孪生模型引领智能化转型

在科技日新月异的今天&#xff0c;煤矿行业也迎来了前所未有的发展机遇。在这个充满挑战与机遇的时代&#xff0c;煤矿运输数字孪生模型以其独特的魅力和巨大的潜力&#xff0c;引领着煤矿运输领域走向智能化、高效化的新时代。 数字孪生模型&#xff0c;就是在虚拟世界中构建一…