react只停留在表层?五大知识点带你梳理进阶知识

五大知识点带你梳理react进阶知识

  • ✉️前言
  • 📧一、props
    • 1、PropTypes与DefaultProps应用
      • (1)PropTypes
      • (2)defaultProps
    • 2、props,state与render函数
  • 📨二、React中的虚拟DOM
    • 1、什么是虚拟DOM
      • (1)第一种方案
      • (2)第二种方案
      • (3)第三种方案
    • 2、虚拟DOM中的 Diff 算法
  • 📩三、React中ref的使用
  • 📦四、React中的生命周期
    • 1、生命周期函数是什么
    • 2、生命周期图例
  • 📪五、React中使用CSS动画效果
    • 1、普通用法
    • 2、react-transition-group
      • (1)初次探索
      • (2)进阶探索
  • 📮六、结束语
  • 🗳️彩蛋

✉️前言

对于 react 的表层来说,我们可能经常听说的是声明式开发单向数据流组件化方式开发等等。那么,进一步来讲的话,我们还需要了解的是 reactprops ,虚拟 DOMref 以及过渡动画等更多新的知识点。

那在下面的这篇文章中,将来探索关于 react 的进阶知识。

叮,下面开始本文的介绍~🤪

📧一、props

1、PropTypes与DefaultProps应用

(1)PropTypes

react 中,有时候我们要对组件中的某个属性进行格式校验,这个时候我们就需要用到 propTypes下面给出一些常见的例子:

// 表示要对TodoItem这个组件做属性的校验
TodoItem.propTypes = {// isRequired 表示必须有值test: PropTypes.string.isRequired,// 表示content的propTypes必须是string类型,那string类型的校验是从PropTypes这个包里面拿到的content: PropTypes.string,// 表示detail可以是一个number或者string的语法detail: PropTypes.arrayOf(PropTypes.number, PropTypes.string),// 表示deleteItem必须是一个函数deleteItem: PropTypes.func,// 表示index必须是一个数字类型index: PropTypes.number
}

(2)defaultProps

有时候,对于某个属性来说,我们希望给它个初始值,那这个时候就需要用到 defaultProps示例如下:

TodoItem.defaultProps = {test: 'hello world'
}

上面的代码表明,当 test 属性没有被赋值时,那么它将被赋予一个初始值,值为 hello world

2、props,state与render函数

react 中,定义一个组件时,经常会看到 propsstaterender 。那他们三者是怎么样的关系呢?

首先我们要想一个问题:为什么数据发生变化,页面就会跟着变化呢?

原因在于,页面是由 render 函数渲染出来的,当数据 state 发生变化时, render 函数就会被重新的执行一次。

同时,当父组件render 函数被运行时,它的子组件render 都将被重新运行。

📨二、React中的虚拟DOM

1、什么是虚拟DOM

(1)第一种方案

传统实现虚拟 DOM 的思路:

  • 先定义 state ,也就是数据;
  • 编写JSX 模板内容;
  • 数据和模板进行结合,生成真是的 DOM ,进而将内容显示到页面上;
  • 如果遇到要替换数据时,则把数据和模板进行结合,生成真实的 DOM ,来替换原始的 DOM

存在缺陷:

  • 第一次生成了一个完整的 DOM 片段;
  • 第二次又生成了一个完整的 DOM 片段;
  • 第二次的 DOM 替换第一次的 DOM ,非常耗费性能。

(2)第二种方案

传统实现虚拟 DOM 的思路改进版:

  • 先定义 state ,即数据;
  • 编写 JSX 模板内容;
  • 数据和模板进行结合,生成真实的 DOM ,并展示;
  • state 的数据发生改变;
  • 继续,把数据和模板进行结合,生成真实的 DOM ,并不是直接替换原始的 DOM
  • 将新的 DOM 和原始的 DOM 做比较,并找出差异
  • 找到新的 Dom 中发生的变化;
  • 只用DOM变化的数据,来替换掉DOM 中的数据。

存在缺陷:

  • 性能的提升并不明显

(3)第三种方案

react 中实现虚拟 DOM 的思路:

  • 先定义 state ,即数据;

  • 编写 JSX 模板内容;

  • 数据和模板进行结合,生成虚拟 DOM (虚拟 DOM 就是一个 JS 对象,用它来描述真实 DOM )。👉(损耗了性能)

    <div id="abc"><span>hello world</span></div>
    ['div', {id: 'abc'}, ['span', {}, 'hello world']]
    
  • 用虚拟 DOM 的结构生成真实的 DOM ,来进行显示;

  • state 发生变化时,数据 + 模板生成新的虚拟 DOM👉(极大的提升了性能)

<div id="abc"><span>monday</span></div> 
['div', {id: 'abc'}, ['span', {}, 'monday']]
  • 比较 原始虚拟 DOM新的虚拟 DOM 的区别,找到其中的区别是 span 中的内容;
  • 直接操作 DOM ,改变 span 的内容;
  • 因此, React 的虚拟 DOM 主要经历的过程是: JSXcreateElement → 虚拟 DOMJS 对象 )→ 真实的 DOM

react 虚拟 DOM 的优点:

  • 极大的提升了性能;
  • 它使得跨端应用得以实现,这要谈到 react 中的一个概念,react native
  • react 使用可以编写原生应用,像 AndroidIOS 开发,这些都是操作真实 DOM
  • react 使得编写这些原生应用得以使用。

2、虚拟DOM中的 Diff 算法

  • reactsetState 的性能优化,它会把多次 setState 结合成一次 setState
  • 虚拟 DOM 使用 diff 算法做比较,只在同层做比较,不跨级做比较
  • 同层比对的算法比较简单,而算法简单带来的直接好处就是速度非常快;
  • 虽然可能会造成 DOM 渲染上的一些浪费,但是呢,它也极大的减少了两个虚拟 DOM 之间进行比较时,性能上的消耗。

📩三、React中ref的使用

react 中建议的是,希望我们可以用数据驱动的形式来编写代码,尽量不要操作 DOM 。但有时候,我们在做一些极其复杂业务的时候,比如各种震撼动画,不可避免的还是会用到一些原生的 DOM 标签。因此, ref 帮助我们在 react 中直接获取 DOM 元素的时候来进行使用。

一般情况下,我们尽量不使用 ref 。如果用 ref 时,会出现各种各样的问题。同时,当使用 refsetState 时,要注意一些存在的坑

比如,当 refsetState 相关联使用时,要注意, setState 是一个异步函数,往往会在同步代码执行完毕后再执行异步代码。因此,如果我们希望同步代码执行顺序在 setState 之后时,可以在 setState 接受的第二个参数中,再增加一个回调函数来进行调用,这样就可以达到我们的效果啦!

render() {return (<ul ref={(ul) => this.ul = ul}>{this.getTodoItem()}</ul>)
}this.setState((prevState) => ({list: [...prevState.list, prevState.inputValue],inputValue: ''
}), () => {console.log(this.ul.querySelectorAll('div').length)
});

📦四、React中的生命周期

1、生命周期函数是什么

所谓生命周期函数,指的是在某一个时刻,组件会自动调用执行的函数。那 react 的生命周期都有哪一些呢?

阶段生命周期含义
MountingcomponentWillMount①当组件即将被挂载到页面的时刻时自动执行,即在页面挂在之前执行;②只在组件被第一次挂在到页面上才会执行;
Mounting/Updationrender页面挂载时被执行
MountingcomponentDidMount会在组件被挂载到页面之后,自动被执行;只在组件被第一次挂在到页面上才会执行
UpdationcomponentWillReceiveProps①当一个组件从父组件接收参数;②只要父组件的render函数被执行了,子组件的这个生命周期函数就会被执行;③如果这个组件第一次存在于父组件中,不会执行;④如果这个组件之前已经存在于父组件中,才会被执行;
UpdationcomponentWillUpdate①组件被更新之前,她会自动执行;②但是它是在shouldComponentUpdate之后被执行,如果shouldComponentUpdate返回true时,它才执行;如果返回false,这个函数就不会被执行了。
UpdationcomponentDidUpdate组件更新完成之后,它会被执行。
UpdationshouldComponentUpdate组件被更新之前,它会被自动被执行;此生命周期返回一个布尔值
UnmountingcomponentWillUnmount当这个组件即将被从页面中剔除的时候,会被执行。

2、生命周期图例

下面用一张图来展示 react 中生命周期的执行效果:

react生命周期

📪五、React中使用CSS动画效果

1、普通用法

我们来看一下,在 react 中,如何使用 css3 所提供的动画效果。具体代码如下:

.show {animation: show-item 2s ease-in forwards;
}.hide {animation: hide-item 2s wase-in forwards;
}@keyframes show-item {0% {oppacity: 0;color: red;}50% {opacity: 0.5;color: green;}100% {opacity: 1;color: blue;}
}

2、react-transition-group

(1)初次探索

有时候,我们可能会想要实现一些很复杂的动画,这个时候 css3 提供的是不够的。因此,我们还需要一点 js 来加以辅助实现更为复杂的动画。这个时候就有谈到 react 中的 react-transition-group 动画。

假设我们想要实现,当点击一个按钮时,一行文字渐隐渐显的实现,那该怎么处理呢?

首先,我们在项目的 src 文件夹下新增一个组件,命名为 App.js具体代码如下:

import React, { Component, Fragment } from 'react';
import { CSSTransition } from 'react-transition-group';
import './style.css';class App extends Component {constructor(props) {super(props);this.state = {show: true}this.handleToggle = this.handleToggle.bind(this);}render() {return (<Fragment>{/* onEntered指的是在某一个时刻会自动执行的一个函数当入场动画结束时,onEntered将会被执行*/}<CSSTransitionin={this.state.show}timeout={1000}classNames='fade'unmountOnExitonEntered={(el) => { el.style.color = "blue" }}appear={true}><div>hello</div></CSSTransition><button onClick={this.handleToggle}>toggle</button></Fragment>)}handleToggle() {this.setState({show: this.state.show ? false : true})}
}export default App;

之后新增一个 CSS 文件,命名为 style.css具体代码如下:

/* 入场动画执行的第一个时刻,即刚要入场的这个瞬间 */
/* fade-appear用于实现渐隐渐现的效果 */
.fade-enter,
.fade-appear {opacity: 0;
}/* 入场动画执行的第二个时刻,到入场动画执行完成之前的一个时刻 */
.fade-enter-active,
.fade-appear-active {opacity: 1;transition: opacity 1s ease-in;
}/* 当整个入场动画执行完成之后 */
.fade-enter-done {opacity: 1;
}/* 表示出场动画执行的第一个时刻 */
.fade-exit {opacity: 1;
}/* 整个出场的过程 */
.fade-exit-active {opacity: 0;transition: opacity 1s ease-in;
}/* 当整个出场动画执行完成时 */
.fade-exit-done {
}

此时我们来看下浏览器的显示效果:

css动画初阶探索

(2)进阶探索

上面我们只是改变了一项数据。现在,如果我们想要点击就新增一项过渡效果,这又该如何处理呢?

我们来改造下 App.js 文件的代码。具体代码如下:

import React, { Component, Fragment } from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import './style.css';class App extends Component {constructor(props) {super(props);this.state = {show: true,list: []}this.handleToggle = this.handleToggle.bind(this);}render() {return (<Fragment>{/* onEntered指的是在某一个时刻会自动执行的一个函数当入场动画结束时,onEntered将会被执行*/}<TransitionGroup>{this.state.list.map((item, index) => {return (<CSSTransitionin={this.state.show}timeout={1000}classNames='fade'unmountOnExitonEntered={(el) => { el.style.color = "blue" }}appear={true}key={index}><div>{item}</div></CSSTransition>)})}</TransitionGroup><button onClick={this.handleToggle}>toggle</button></Fragment>)}handleToggle() {this.setState((prevState) => {return {list: [...prevState.list, 'item']}})}
}export default App;

此时浏览器的运行效果如下:

css动画进阶探索

对于这种类型的动画来说,我们通过 TransitionGroup 对外层进行包裹,之后通过 CSSTransition 对里层进行包裹,进而达到我们最终的效果。

📮六、结束语

在上面这篇文章中,我们讲解了 react 中的 props ,同时,还简单的了解了虚拟 DOM 的内容。除此之外呢,还学习了 ref 的使用,以及 react 中的酷炫的过渡动画。当然,最为重要的一点是, react 中的生命周期函数

那到这里, react 的进阶知识讲到这里就结束了。不知道小伙伴们对 react 是否又有进一步的认识呢?

🗳️彩蛋

  • 关注公众号星期一研究室,第一时间关注优质文章,更有面试专栏待你解锁~
  • 如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉
  • 以上就是本文的全部内容!我们下期见!🥂🥂🥂

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

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

相关文章

解决 WPF 绑定集合后数据变动界面却不更新的问题

解决 WPF 绑定集合后数据变动界面却不更新的问题独立观察员 2020 年 9 月 9 日在 .NET Core 3.1 的 WPF 程序中打算用 ListBox 绑定显示一个集合&#xff08;满足需求即可&#xff0c;无所谓什么类型的集合&#xff09;&#xff0c;以下是 Xaml 代码&#xff08;瞟一眼就行&…

「offer来了」面试中必考的15个html知识点

「面试专栏」前端面试之html篇⚡序言⭐一、题集内容抢先看&#x1f320;二、规范相关1、你如何理解HTML结构的语义化2、浏览器是怎么对 Html5 的离线储存资源进行管理和加载的呢3、HTML W3C的标准4、Doctype作用? 严格模式与混杂模式如何区分&#xff1f;它们有何意义?5、vie…

leetcode700. 二叉搜索树中的搜索

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*…

「offer来了」1张思维导图,6大知识板块,带你梳理面试中CSS的知识点!

「面试专栏」前端面试之css篇⌛序言✏️一、CSS框架先梳理&#x1f58c;️二、基础样式问题1、请你讲一讲css的权重和优先级&#xff08;1&#xff09;权重&#xff08;2&#xff09;优先级2、说一下CSS的position属性3、span 标签是否可以设置宽高&#xff0c; margin 和 padd…

动态代理的理解

一:动态代理和静态代理的区别 静态代理&#xff1a;了解设计模式中的代理模式的童鞋应该都知道&#xff0c;如果想要生成代理类&#xff0c;需要让代理类和被代理类实现同一个接口&#xff0c;并且在代理类中添加被代理类的引用&#xff0c;代理类方法实现中添加代理逻辑&…

.NET Core 下的爬虫利器

爬虫大家或多或少的都应该接触过的&#xff0c;爬虫有风险&#xff0c;抓数需谨慎。本着研究学习的目的&#xff0c;记录一下在 .NET Core 下抓取数据的实际案例。爬虫代码一般具有时效性&#xff0c;当我们的目标发生改版升级&#xff0c;规则转换后我们写的爬虫代码就会失效&…

Redux从入门到进阶,看这一篇就够了!

Redux&#xff0c;带你从入门到进阶&#x1f302;序言☂️一、基础知识1、Redux概念简述2、Redux的工作流程&#x1f383;二、使用Antd实现TodoList页面布局1、在项目中使用Antd2、使用Antd实现TodoList的基本布局3、创建redux中的store&#xff08;1&#xff09;创建store&…

ASP.NET Core 3.x控制IHostedService启动顺序浅探

想写好中间件&#xff0c;这是基础。一、前言今天这个内容&#xff0c;基于于ASP.NET Core 3.x。从3.x开始&#xff0c;ASP.NET Core使用了通用主机模式。它将WebHostBuilder放到了通用的IHost之上&#xff0c;这样可以确保Kestrel可以运行在IHostedService中。我们今天就来研究…

com.mysql.cj.exceptions.InvalidConnectionAttributeException

一:java连接数据库报错 com.mysql.cj.exceptions.InvalidConnectionAttributeException 二:报错原因 MySQL jdbc 6.0 版本以上必须配置“serverTimezone”参数 UTC代表的是全球标准时间 若我们使用的时间是北京时区也就是东八区&#xff0c;领先UTC八个小时。url的时区使用…

Istio Pilot 源码分析(一)

张海东&#xff0c; ‍多点生活&#xff08;成都&#xff09;云原生开发工程师。Istio 作为目前 Servic Mesh 方案中的翘楚&#xff0c;吸引着越来越多的企业及开发者。越来越多的团队想将其应用于微服务的治理&#xff0c;但在实际落地时却因为不了解 Istio 黑盒中的运行机制而…

结营啦!有缘相聚于青训,未来高处见呀~~

&#x1f4f8;叮&#xff01; 记 字节跳动第一届青训营顺利结营啦&#xff01; 从8月份的青训营&#xff0c;到9月份的实训营&#xff0c;搁置了许久的结营心得终于拾起来辽&#xff01; &#x1f3ac;开营进行时 从答疑会开始&#xff0c;负责人仔细的阐述了本次训练营的…

MVC三层架构(详解)

1:初始MVC (1):三层架构 三层架构是指&#xff1a;视图层 View、服务层 Service&#xff0c;与持久层 Dao。它们分别完成不同的功能。 View 层&#xff1a;用于接收用户提交请求的代码在这里编写。 Service 层&#xff1a;系统的业务逻辑主要在这里完成。 Dao 层&#xff1a;…

「offer来了」保姆级巩固你的js知识体系(4.0w字)

「面试专栏」前端面试之JavaScript篇&#x1f9d0;序言&#x1f973;思维导图环节&#x1f60f;一、JS规范1、说几条JavaScript的基本规范。2、对原生JavaScript的了解。3、说下对JS的了解吧。4、JS原生拖拽节点5、谈谈你对ES6的理解6、知道ES6的class嘛&#xff1f;7、说说你对…

写作是人生最大的杠杆

职场&认知洞察 丨 作者 / 易洋 这是findyi公众号的第71篇原创文章不知不觉&#xff0c;公众号写作已经持续了9个月了。去年11月底&#xff0c;心血来潮写了第一篇文章&#xff0c;更多是为了复盘过去的一些工作经历。在前几天&#xff0c;读者数突破了3万&#xff0c;虽然…

拥塞控制(详解)

一&#xff1a;TCP的拥塞控制 1:是什么 (1):是什么(拥塞现象) 网络的 吞吐量 与 通信子网 负荷(即通信子网中正在传输的分组数)有着密切的关系。当 通信子网 负荷比较小时,网络的 吞吐量 (分组数/秒)随网络负荷(每个 节点 中分组的平均数)的增加而线性增加。当网络负荷增加到…

解决 WPF 绑定集合后数据变动界面却不更新的问题(使用 ObservableCollection)

解决 WPF 绑定集合后数据变动界面却不更新的问题独立观察员 2020 年 9 月 9 日在 .NET Core 3.1 的 WPF 程序中打算用 ListBox 绑定显示一个集合&#xff08;满足需求即可&#xff0c;无所谓什么类型的集合&#xff09;&#xff0c;以下是 Xaml 代码&#xff08;瞟一眼就行&…

Kubernetes Liveness and Readiness Probes

在设计关键任务、高可用应用程序时&#xff0c;弹性是要考虑的最重要因素之一。当应用程序可以快速从故障中恢复时&#xff0c;它便具有弹性。云原生应用程序通常设计为使用微服务架构&#xff0c;其中每个组件都位于容器中。为了确保Kubernetes托管的应用程序高可用&#xff0…

「offer来了」2种递进学习思维,24道计网题目,保姆级巩固你的计网知识体系

「面试专栏」前端面试之计算机网络篇⚾序言&#x1f3d0;一、基础知识环节1、专栏学习2、书籍学习⚽二、思维导图环节&#x1f3b3;三、OSI七层模型1、OSI模型是什么&#xff1f;2、OSI七层模型遵循原则&#x1f3cf;四、TCP与UDP1、TCP与UDP的区别2、TCP/UDP的优缺点&#xff…

leetcode236. 二叉树的最近公共祖先

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:/**思路:1.这里我们需要的是从底向上开…

进击吧! Blazor !第二期 页面制作

Blazor 是一个 Web UI 框架&#xff0c;可通过 WebAssembly 在任意浏览器中运行 .Net 。Blazor 旨在简化快速的单页面 .Net 浏览器应用的构建过程&#xff0c;它虽然使用了诸如 CSS 和 HTML 之类的 Web 技术&#xff0c;但它使用 C&#xff03;语言和 Razor 语法代替 JavaScrip…