react基础-生命周期render props模式高阶组件原理揭秘

news2024/9/27 17:33:36

组件生命周期(★★★)

目标

  • 说出组件生命周期对应的钩子函数
  • 钩子函数调用的时机

概述

意义:组件的生命周期有助于理解组件的运行方式,完成更复杂的组件功能、分析组件错误原因等

组件的生命周期: 组件从被创建到挂载到页面中运行,再到组件不在时卸载的过程

生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数

构造函数的作用:为开发人员在不同阶段操作组件提供了实际

生命周期阶段

请添加图片描述

创建时(挂载阶段)

  • 执行时机:组件创建时(页面加载时)
  • 执行顺序

请添加图片描述

请添加图片描述

更新时

执行时机:setState()、 forceUpdate()、 组件接收到新的props

说明:以上三者任意一种变化,组件就会重新渲染

执行顺序:

请添加图片描述

请添加图片描述

卸载时

执行时机:组件从页面中消失

作用:用来做清理操作

请添加图片描述

不常用的钩子函数

旧版的生命周期钩子函数

请添加图片描述

新版完整生命会走棋钩子函数

请添加图片描述

getDerivedStateFromProps()
  • getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容
  • 不管原因是什么,都会在每次渲染前触发此方法
shouldComponentUpdate()
  • 根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染
  • 当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。返回值默认为 true
getSnapshotBeforeUpdate()
  • getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()
  • 此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等

render-props模式 (★★★)

目标

  • 知道render-props模式有什么作用
  • 能够说出render-props的使用步骤

React组件复用概述

  • 思考:如果两个组件中的部分功能相似或相同,该如何处理?
  • 处理方式:复用相似的功能
  • 复用什么?
    • state
    • 操作state的方法
  • 两种方式:
    • render props模式
    • 高阶组件(HOC)
  • 注意: 这两种方式不是新的API,而是利用React自身特点的编码技巧,演化而成的固定模式

思路分析

  • 思路:将要复用的state和操作state的方法封装到一个组件中

  • 如何拿到该组件中复用的state

    • 在使用组件时,添加一个值为函数的prop,通过函数参数来获取

请添加图片描述

  • 如何渲染到任意的UI

    • 使用该函数的返回值作为要渲染的UI内容

请添加图片描述

使用步骤

  • 创建Mouse组件,在组件中提供复用的逻辑代码
  • 将要复用的状态作为 props.render(state)方法的参数,暴露到组件外部
  • 使用props.render() 的返回值作为要渲染的内容

请添加图片描述

示例demo

class Mouse extends React.Component {
    // 鼠标位置状态
    state = {
        x: 0,
        y: 0
    }

    // 监听鼠标移动事件
    componentDidMount(){
        window.addEventListener('mousemove',this.handleMouseMove)
    }
    handleMouseMove = e => {
        this.setState({
            x: e.clientX,
            y: e.clientY
        })
    }
    render(){
        // 向外界提供当前子组件里面的数据
        return this.props.render(this.state)
    }
}
class App extends React.Component {
    render() {
        return (
            <div>
                App
                <Mouse render={mouse => {
                    return <p>X{mouse.x}Y{mouse.y}</p>
                }}/>
            </div>
        )
    }
}
ReactDOM.render(<App />,document.getElementById('root'))

children代替render属性

  • 注意:并不是该模式叫 render props就必须使用名为render的prop,实际上可以使用任意名称的prop
  • 把prop是一个函数并且告诉组件要渲染什么内容的技术叫做: render props模式
  • 推荐:使用childre代替render属性

请添加图片描述

优化代码

  • 推荐给render props模式添加props校验

  • 请添加图片描述

请添加图片描述

高阶组件 (★★★)

目标

  • 知道高阶组件的作用
  • 能够说出高阶的使用步骤

概述

  • 目的:实现状态逻辑复用
  • 采用 包装模式
  • 手机:获取保护功能
  • 手机壳:提供保护功能
  • 高阶组件就相当于手机壳,通过包装组件,增强组件功能

请添加图片描述

思路分析

  • 高阶组件(HOC、Higher-Order Component) 是一个函数,接收要包装的组件,返回增强后的组件

请添加图片描述

  • 高阶组件内部创建了一个类组件,在这个类组件中提供复用的状态逻辑代码,通过prop将复用的状态传递给被包装组件WrappedComponent

请添加图片描述

使用步骤

  • 创建一个函数,名称约定以with开头
  • 指定函数参数,参数应该以大写字母开头
  • 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
  • 在该组件中,渲染参数组件,同时将状态通过prop传递给参数组件
  • 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面

包装函数

// 定义一个函数,在函数内部创建一个相应类组件
function withMouse(WrappedComponent) {
    // 该组件提供复用状态逻辑
    class Mouse extends React.Component {
        state = {
            x: 0,
            y: 0
        }
        // 事件的处理函数
        handleMouseMove = (e) => {
            this.setState({
                x: e.clientX,
                y: e.clientY
            })
        }
        // 当组件挂载的时候进行事件绑定
        componentDidMount() {
            window.addEventListener('mousemove', this.handleMouseMove)
        }
        // 当组件移除时候解绑事件
        componentWillUnmount() {
            window.removeEventListener('mousemove', this.handleMouseMove)
        }
        render() {
            // 在render函数里面返回传递过来的组件,把当前组件的状态设置进去
            return <WrappedComponent {...this.state} />
        }
    }
    return Mouse
}

哪个组件需要加强,通过调用withMouse这个函数,然后把返回的值设置到父组件中即可

function Position(props) {
    return (
        <p>
            X:{props.x}
            Y:{props.y}
        </p>
    )
}
// 把position 组件来进行包装
let MousePosition = withMouse(Position)

class App extends React.Component {
    constructor(props) {
        super(props)
    }
    render() {
        return (
            <div>
                高阶组件
                <MousePosition></MousePosition>
            </div>
        )
    }
}

设置displayName

  • 使用高阶组件存在的问题:得到两个组件的名称相同
  • 原因:默认情况下,React使用组件名称作为displayName
  • 解决方式:为高阶组件设置displayName,便于调试时区分不同的组件
  • displayName的作用:用于设置调试信息(React Developer Tools信息)
  • 设置方式:

请添加图片描述

传递props

  • 问题:如果没有传递props,会导致props丢失问题
  • 解决方式: 渲染WrappedComponent时,将state和props一起传递给组件

请添加图片描述

小结

  • 组件通讯是构建React应用必不可少的一环
  • props的灵活性让组件更加强大
  • 状态提升是React组件的常用模式
  • 组件生命周期有助于理解组件的运行过程
  • 钩子函数让开发者可以在特定的时机执行某些功能
  • render props 模式和高阶组件都可以实现组件状态逻辑的复用
  • 组件极简模型: (state,props) => UI

React原理

目标

  • 能够知道setState()更新数据是异步的
  • 能够知道JSX语法的转化过程

setState()说明 (★★★)

更新数据

  • setState()更新数据是异步的
  • 注意:使用该语法,后面的setState不要依赖前面setState的值
  • 多次调用setState,只会触发一次render

推荐语法

  • 推荐:使用 setState((state,props) => {}) 语法
  • 参数state: 表示最新的state
  • 参数props: 表示最新的props

请添加图片描述

第二个参数

  • 场景:在状态更新(页面完成重新渲染)后立即执行某个操作
  • 语法:setState(update[,callback])

请添加图片描述

JSX语法的转化过程 (★★★)

  • JSX仅仅是createElement() 方法的语法糖(简化语法)
  • JSX语法被 @babel/preset-react 插件编译为createElement() 方法
  • React 元素: 是一个对象,用来描述你希望在屏幕上看到的内容

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通用机器人里程碑?谷歌展示全球首个多任务AI智能体

目录 两大硬核科技支撑通用机器人研发&#xff08;1&#xff09;自生成训练数据&#xff08;2&#xff09;基于多模态模型 科技巨头同台比拼 中国产业链凸显性价比优势发展初期硬件先行 运动模块价值量最高 已学会套圈、搭积木、抓水果…… 人工智能和机器人&#xff0c;总是不…

MES生产管理系统与ERP系统的集成以及优势

导言&#xff1a; 在当今数字化转型的浪潮中&#xff0c;企业越来越意识到整合各个部门的数据和流程的重要性。MES生产管理系统和ERP系统是两个关键的管理工具&#xff0c;它们在企业中发挥着不可或缺的作用。本文将探讨企业MES管理系统与ERP系统进行集成&#xff0c;以及这种…

它如何做到让我们持久且不感疲劳

写在前面 随着科技的进步和数字化生活的兴起&#xff0c;人们长时间使用显示器的需求增加&#xff0c;越来越多的人戴眼镜并且面临眼睛问题。显示器屏幕灯在当今社会也逐渐扮演着不可或缺的角色。 首先&#xff0c;显示器屏幕灯能够提供必要的亮度&#xff0c;确保我们在各种…

pyhton-docx表格合并单元格

合并单元格需要指定两个单元格&#xff0c; from docx_utils import set_table_singleBoard from docx import Documentdocument Document() table document.add_table(rows3, cols3) # 创建一个包含 3 行 3 列的表格 table.cell(0, 0).merge(table.cell(0, 1)) # 合并第一…

用正则表达式进行input框的限制输入

vue项目可以用input事件输入 1.限制input输入框只能输入大小写字母、数字、下划线的正则表达式&#xff1a; 用户名< input type"text" placeholder"只包含数字字母下划线" onkeyup"this.valuethis.value.replace(/[^\w_]/g,);"> 2.限…

linux如何修改sudoers文件,将非root用户加入到 sudoers 文件中

需求 由于在非 root 用户下执行 sudo 命令会报错 cc 不在 sudoers 文件中。此事将被报告。所以需要将 cc 这个用户加入到 sudoers 文件中进行授权 解决 要修改 sudoers 文件&#xff0c;您需要以 root 用户身份进行操作。以下是一种常见的方法&#xff1a; 1、使用 root 用…

Linux文件管理(创建 删除 复制 剪切 打包 压缩 解压缩)全总结

目录 一、Linux下文件命名规则 1、可以使用哪些字符&#xff1f; 2、文件名的长度 3、文件名的大小写 4、Linux文件扩展名 二、Linux下的文件管理 1、文件夹创建 ① mkdir创建文件夹 ② mkdir -p递归创建文件夹&#xff08;目录&#xff09; ③ 使用mkdir同时创建多个…

nacos批量信息获取-GitNacosConfig

声明&#xff1a;文中涉及到的技术和工具&#xff0c;仅供学习使用&#xff0c;禁止从事任何非法活动&#xff0c;如因此造成的直接或间接损失&#xff0c;均由使用者自行承担责任。 点点关注不迷路&#xff0c;每周不定时持续分享各种干货。 原文链接&#xff1a;众亦信安&a…

Leetcode-每日一题【234.回文链表】

题目 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1]输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;head…

【Golang | runtime】runtime.Caller和runtime.Callers的使用和区别

环境&#xff1a; go version go1.18.2 1、runtime.Caller 函数func runtime.Caller(skip int) (pc uintptr, file string, line int, ok bool) 作用 获取函数Caller的调用信息 参数 skip: 0时&#xff0c;返回调用Caller的函数A的pc(program counter)、所在文件名以及Cal…

SI12T触摸按键芯片兼容TMS12资料

Si12T 是一款具有自动灵敏度校准功能的 12 通道电容传感器&#xff0c;其工作电压 范围为 1.8 ~ 5.0 V 。 Si12T 设置 IDLE 模式来节省功耗&#xff0c;此时&#xff0c;功耗电流为 3.5 A3.3V 。 Si12T 有三种特殊功能&#xff1a;一种是通道 1 上的嵌入式电源键…

体验Kubernetes(k8s),使用minikube搭建单机k8s

文章目录 一、windows&#xff1a;使用Minikube搭建单节点K8s1、安装VirtualBox2、安装kubectl3、安装minikube4、使用minikube搭建k8s 二、centos&#xff1a;使用minikube搭建单节点k8s1、安装docker2、下载kubectl&minikube与安装3、搭建单机k8s4、体验pod 一、windows&…

【计算机网络】MAC地址、IP地址、ARP协议

1.总概念 2.MAC地址 2.1 MAC地址作用 2.2 网络适配器&#xff08;网卡&#xff09; 2.3 概念 2.4 MAC地址格式 2.5 MAC地址发送顺序 单播MAC地址 广播MAC地址 多播MAC地址 随机MAC地址&#xff08;信息安全和隐私保护&#xff09; 2.6小结 3. IP地址 3.1 IP地址作用 3.2 网络…

【C#】实体类和DataTable之间相互转换,实体反射动态遍历列

在实际项目中&#xff0c;经常会用到数据之间的相互转换&#xff0c;序列化和反序列化就是常见场景。这里我们只简单聊聊实体类和DataTable之间的相互转换&#xff0c;可以用于不同业务场景使用。 目录 1、DataTable转Model2、Model转DataTable3、反射概念3.1、Type 类型3.2、A…

力扣 669. 修剪二叉搜索树

题目来源&#xff1a;https://leetcode.cn/problems/trim-a-binary-search-tree/description/ C题解1&#xff1a;递归法。当前节点为空时返回空&#xff0c;不为空时对其值进行分类讨论。以low为例&#xff0c;当前节点值等于low时&#xff0c;意味着其左子树都要丢弃&#xf…

uniapp小程序进入横屏页面后竖屏页面样式错乱放大

问题描述&#xff1a;进入横屏页面后退出再进入一个竖屏页面&#xff0c;样式会错乱放大 解决方法 1.新增一个空白页&#xff0c;blank.vue <template> </template><script>export default {data() {return {}},onLoad(options) {uni.navigateBack({delta…

青岛大学_王卓老师【数据结构与算法】Week03_10_线性表的链式表示和实现10_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c;另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础–…

ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器

ASP.NET MVC 过滤器 可在执行管道的前后特定阶段执行代码。过滤器可以配置为全局有效、仅对控制器有效或是仅对 Action 有效。 查看或下载演示代码. 过滤器如何工作&#xff1f; 不同的过滤器类型会在执行管道的不同阶段运行&#xff0c;因此它们各自有一套适用场景。根据你…

攻防视角下的信息收集组合拳-蓝队视角

攻防视角下的信息收集组合拳-蓝队视角 背景蓝队角度一、攻击前的信息收集1、企业资产梳理2、企业敏感文件清理 二、被攻击后的信息收集1、入侵成功信息收集技巧2、入侵失败信息收集技巧-锁定攻击IP反制技巧 背景 红蓝对抗中&#xff0c;最为重要的就是信息收集&#xff0c;无论…

国外追踪水资源短缺的6幅干旱地图

今天为大家分享国外6个干旱地图&#xff0c;这些地图使我们能够通过最新信息了解干旱的严重程度和范围。 它们通过捕捉水的可用性等关键信息&#xff0c;以便我们能够主动规划和应对干旱的影响。 全球干旱信息系统(GDIS) 地图网址&#xff1a; https://experience.arcgis.co…