• React教程(详细版)


    一、简介(背景)

    本文篇幅较多,建议耐心看完,我相信多少会对你有所帮助!

    1.1、概念

    它是一个将数据渲染为HTML视图 的js库

    1.2、原生js痛点

    • 用dom的API去操作dom,繁琐且效率低
    • 用js直接操作dom,浏览器会进行大量的回流和重绘
    • 原生js没有组件化的编程方案,代码复用性低,哪怕有模块话的概念,但模块化也只能拆解一个个js,对样式和结构也没办法拆解,组件化就相当于3剑客整体拆解,成为一个个的小功能

    1.3、React特点

    • 采用组件化模式,声明式编码,提高开发效率和组件复用性
    • 在React Native中可以用react预发进行安卓、ios移动端开发
    • 使用虚拟dom和有些的diffing算法,尽量减少与真实dom的交互,提高性能

    二、React初体验

    2.1、html中使用react

    需求:往div中添加一个h1标签

    在这里插入图片描述

    代码注解:这里涉及到3个库文件,一个react(核心库),react-dom(用于支持react操作dom的)还有一个babel(将jsx语法转成js语法,因为浏览器只能识别js),还有就是script标签中的type需要写成text/babel,因为script标签中要写jsx的语法,这里再说一点,就是你引入了react-dom库,就可以使用ReactDOM变量了,跟以前学习jquery一样,引入jquery文件就可以使用$和jquery是同样的道理

    2.1.1、 创建虚拟dom的方式

    ①使用原生js的方式去写(一般不用)
    在这里插入图片描述

    代码注解:使用原生js来创建虚拟dom时,此时script标签的type就不需要写成text/babel,写成原来的text/javascript就可以了,同时也可以删除babel库了,因为不需要它进行转换,浏览器本身就能识别

    ②使用jsx语法创建(就是最开始的那种方式)

    这里可能会有小伙伴会问,为什么不用js来创建dom呢?我看写起来也还行啊,这是因为你还没见过结构嵌套的情况,当需求改为h1标签内再嵌套一个span标签,你怎么办?是不是后面还得再继续套React.createElement(‘span’,{},‘span内容’) ,那如果继续嵌套呢?是不是废了。。。,所以这里就能看出jsx的好处了,其实babel将jsx转换后的代码就相对于用原生js写的那样,只不过这些不用你写,babel帮你转换

    2.1.2、 关于创建的虚拟dom

    1. 本质上其实就是一个object对象;
    2. 虚拟dom上的属性比较少,真实dom属性多,因为虚拟dom只在recat内部使用,用不到那么多的属性
    3. 虚拟dom最终会被react转换成真实dom,呈现再页面上

    2.2、JSX语法

    • 定义虚拟dom时不要用引号
    • 标签中引入js表达式要用{}
    • 如果在jsx要写行内样式需要使用style={{coler:red}}形式
    • 样式的类名指定不能写class,要写className;
    • 只有一个根标签
    • 标签必须闭合
    • 标签首字母
      ①若小写字母开头,则会将该标签转为html同名标签,如果没找到,则会报错;
      ②若大写字母开头,则会认为是组件,它就会去找对应的组件,如果没找到,就会报组件未定义的错误;

    三、React面向组件编程

    3.1 安装开发者工具(React Developer Tools )

    这里工具的具体安装方式就不多说了,由两种方式,一种是翻墙,直接在chrome浏览的商城去下载,还有一种方式是在浏览器扩展程序中打开开发者模式,然后导入已下载的插件文件即可

    3.2 组件的分类

    1. 函数式组件(适用于简单组件)
    在这里插入图片描述

    2. 类式组件(适用于复杂组件)
    在这里插入图片描述

    3.3 组件实例对象的三大属性

    3.3.1、 state

    这里我们用一个小需求来说说state和组件内绑定方法这两个问题,需求:点击文本,改变天气状态

    在这里插入图片描述

    上述图片中的例子这样的写法并不能实现我们的需求,为什么?因为changeWeather方法中打印的this是undefined,不是该weather组件的实例对象,自然也就无法拿到该实例对象上的state等属性,更加不用说去改变state中的状态了。。。那为什么会这样的?原因就写在图中,那我们要怎么处理才能让该方法拿到该组件的实例对象呢?来,看下面。。

    在这里插入图片描述

    在构造函数中加一句这个语句就可以了,那这行代码是什么意思呢?
    构造函数中的this永远指向该组件的实例对象,所以=右侧意思就是该组件实例对象自身此时还没有该方法,他就会去原型对象上看有没有,显然这里是有的,然后调用bind方法,该方法做两件事,一、创建一个新的函数;二、函数内的this指向bing()括号中传入的,显然这里是组件实例对象;右侧执行完后,将该方法赋值给了实例对象本身的一个方法名(changeWeather),这样实例对象本身就有一个changeWeather方法了,并且内部this就是组件实例对象,所以此时render中点击调用的那个方法,实际上是this实例对象自身的一个changeWeather方法,而不是写在类中的那个原型对象上的changeWeather方法,我们为了不混淆两个重名的方法,我们区分看一下

    在这里插入图片描述
    好了,接下来我们要做改变状态这件事了,我们要通过react中的内置API(setState方法),不能直接更改state,就像下面这样。
    在这里插入图片描述

    好了,到现在需求已经满足了,但我们要对其简化。。。
    在这里插入图片描述

    上述将state和自定义方法直接写在了类中,这样写的意思就是说,给类组件的实例对象添加了一个state属性和自定义方法,而且这里的自定义方法必须写成箭头函数的形式,因为箭头函数内部是没有this指向的,他会去他外部找this,那此时外部的this就是组件实例对象

    总结:

    • state是组件实例对象最重要的属性,必须是对象的形式

    • 组件被称为状态机,通过更改state的值来达到更新页面显示(重新渲染组件)

    • 组件render中的this指的是组件实例对象

    • 状态数据不能直接赋值,需要用setState()

    • 组件自定义方法中的this为undefined,怎么解决?

      ①将自定义函数改为表达式+箭头函数的形式(推荐)
      ②在构造器中用bind()强制绑定this

    3.3.2、 props

    props就是在调用组件的时候在组件中添加属性传到组件内部去使用

    简单demo:
    在这里插入图片描述
    接下来这里我们想对传入的props属性进行一些必传、默认值、类型的校验,所以就需要用到一个prop-types库

    下载:npm i prop-types --save
    引入:import PropTypes from ‘prop-types’

    在这里插入图片描述
    构造器问题

    构造器仅用于以下两种情况:

    • 通过this.state赋值对象来初始化内部的state
    • 为事件处理函数绑定实例(就是上面的this.changeWeather=this.changeWeather.bind(this))

    但是上述的这两个点我们都有简单的方法来实现,state我们可以用state={name:11}这种直接赋值的方式来实现,自定义事件的话可以通过赋值语句+箭头函数的方式来实现,所以一般开发过程中都不写构造器,还有就是如果一定要写构造器,那么构造器是否接受props,是否传递给props,取决于是否要在构造器中通过this访问props

    函数组件中的props

    在这里插入图片描述

    因为函数组件没有组件实例对象,所以其他两个state和refs是没有的,只有props属性可用,直接在()中接受props对象即可,函数内部就可以结构使用props中的值了

    总结:

    • 每个组件都会有props属性
    • 组件标签的所有属性都保存在props
    • 组件内部不能改变外部传进来的props属性值

    3.3.3 refs属性

    • 字符串形式的ref(这种方式已过时,不推荐使用,因为效率低)

    refs是组件实例对象中的属性,它专门用来收集那些打了ref标签的dom元 素,比方说,组件中的input添加了一个ref=“input1”,那么组件实例中的refs就={input1:input(真实dom)},这样就可以通过this.refs.input1拿到input标签dom了,就不需要想原生js那样通过添加属性id,然后通过document.getElementById(“id”)的方式拿

    • 回调函数形式
      在这里插入图片描述

    直接让ref属性=一个回调函数,为什么这里说是回调函数呢?因为这个函数是你定义的,但不是你调用的,是react在执行render的时候,看到ref属性后跟的是函数,他就会帮你调用了,然后把当前dom标签当成形参传入,所以上述例子这样写,就相当于把当前节点dom赋值给了this.input1,那这个this指的是谁呢?不难理解,这里是箭头函数,本身没有this指向,所以这个this得看外层的,该函数外层是render函数体内,所以this就是组件实例对象,所以ref={c=>this.input1=c}意思就是给组件实例对象添加一个input1,最后要取对应节点dom也直接从this(组件实例中取)

    这里我们再来探讨一个小问题,就是这个ref的回调函数会被执行几次的问题?第一次在页面刚进来执行render渲染的时候,react会把当前节点当成参数赋值给组件实例,当组件更新的时候(状态改变时),它又会执行一次render,这个时候,react官方说明了这点,它会执行两次,第一次是将原先的实例属性清空,传入的是null,第二次再把当前节点传如赋值给组件实例的input1属性,这个在一般开发过程中无关紧要,所以大家知道下有这个情况就可以了,当然它也有解决办法:通过将ref的回调函数定义成类的绑定函数的方式,即ref={this.func},func是定义在类中的方法,func==>{this.input1=c} ,这种方式就可以解决上述执行两次的问题,一般开发中我们写成回调的形式就可以了

    • createRef
      在这里插入图片描述

    代码解读:createRef()方法是React中的API,它会返回一个容器,存放被ref标记的节点,但该容器是专人专用的,就是一个容器只能存放一个节点;
    当react执行到div中第一行时,发现input节点写了一个ref属性,又发线在上面创建了myRef容器,所以它就会把当前的节点存到组件实例的myRef容器中

    注意:如果你只创建了一个ref容器,但多个节点使用了同一个ref容器,则最后的会覆盖掉前面的节点,所以,你通过this.ref容器.current拿到的那个节点是最后一个节点

    四、 React中的事件处理

    1. 通过onXxxx属性指定事件处理函数(小驼峰形式)
    2. 通过event.target可以得到发生事件的Dom元素
    3. 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。

    4.1 高阶函数和函数柯里化

    在这里插入图片描述
    我们写个用到高阶函数和函数柯里化的例子:

    ...其余代码省略
    
    saveFormData=(type)=>{  
    	return (event)=>{
    		this.setState({
    			[type]:event.target.value  
    		})
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    上面代码的saveFormData函数其实就是高阶函数,因为它返回的值是一个函数,而且这个函数就是通过函数柯里化的方式在调用(先是saveFormData函数接收一个参数type,随后返回函数,然后再接收别的参数,然后最终来处理结果(设置state值))

    • 提问1:那为什么要写成这样呢?我直接在函数saveFormData中同时接收两个参数不行吗?
      答:不行,因为你拿不到event,因为这是react帮你处理的

    • 提问2:那还有没有别的方式来实现,不用柯里化处理方式?
      答:有

      //将下面函数的调用方式改为这样就可以了,函数接收方式也改下

      saveFormData=(type,value)=>{
      this.setState({
      [type]:value
      })
      }

    五、 生命周期函数

    5.1 老版的生命周期过程:
    在这里插入图片描述
    挂载时:先执行构造器(constructor)=》组件将要挂载(componentWillMount)=》组件挂载渲染(render)=》组件挂载完成(componentDidMount)=》组件销毁(componentWillUnmount)

    组件内部状态更新:组件是否应该更新(shouldComponentUpdate)=》组件将要更新(componentWillUpdate)=》组件更新渲染(render)=》组件更新完成(componentDidUpdate)

    强制更新:调用this.forceUpdate(),这个api和setState一样都是react自带的,一般这个强制更新很少用,它的执行流程就是比上述的正常更新流程少一步询问是否更新(shouldComponentUpdate)

    父组件重新render:调用组件将要接收新props(componentWillReceiveProps)=》组件是否应该更新(shouldComponentUpdate)=》组件将要更新(componentWillUpdate)=》组件更新渲染(render)=》组件更新完成(componentDidUpdate)

    注意:上述加粗的函数,只有在父组件状态发生改变了,重新调用render时才会调用子组件的componentWillReceiveProps函数,父组件第一次引用子组件的时时不会调用的

    5.2 新版生命周期函数
    在这里插入图片描述

    新版生命周期函数和旧版的差别:新版即将废弃老的3个钩子(componentWillMount、componentWillReceiveProps、componentWillUpdate),新增了2个钩子(getDerivedStateFromProps、getSnapshotBeforeUpdate)

    六、 DOM的Diff算法

    虚拟DOM中的key的作用:

    当状态中的数据发生改变时,react会根据【新数据】生成【新虚拟DOM】,随后react会进行【新虚拟DOM】和【旧虚拟DOM】的diff算法比较,具体的比较规则如下:

    • 若【旧DOM】中找到了与【新DOM】相同的key,则会进一步判断两者的内容是否相同,如果也一样,则直接使用之前的真实DOM,如果内容不一样,则会生成新的真实DOM,替换掉原先的真实DOM
    • 若【旧DOM】中没找到与【新DOM】相同的key,则直接生成新的真实DOM,然后渲染到页面

    用index作为key可能引发的问题

    1. 若对数据进行:逆序添加、逆序删除等破坏顺序的操作时会产生不必要的真实DOM更新,造成效率低下
    2. 如果结构中还包含输入类的dom,会产生错误dom更新,出现界面异常

    开发中如何选择key

    1. 最好选中标签的唯一标识id、手机号等
    2. 如果只是简单的展示数据,用index也是可以的

    七、 脚手架

    使用create-react-app(脚手架工具)创建一个初始化项目

    1、下载脚手架工具:npm i -g create-react-app

    2、创建引用:create-react-app my-app

    3、运行应用:cd my-app(进入应用文件夹),npm start(启动应用)

    7.1 React脚手架配置代理

    • 方法一

    在package.json中追加如下配置

    "proxy":"http://localhost:5000"
    
    • 1

    说明:

    1、优点:配置简单,前端请求资源可以不加任何前缀
    2、缺点:不能配置多个代理(如果请求的不同服务器就不行)
    3、工作方式:当请求了自身3000端口不存在的资源时,那么会转发给5000端口(优先会匹配自身的资源,如果自己有就不会请求5000端口了)

    • 方法二

    1、第一步:创建代理配置文件

    在src下创建配置文件:src/setupProxy.js
    
    • 1

    2、编写代理配置规则
    在这里插入图片描述
    说明:

    1、优点:可以配置多个代理,可以灵活控制请求是否走代理
    2、缺点:配置繁琐,前端请求资源时必须加前缀

    八、 消息订阅-发布机制

    背景:

    原先react传递数据基本用的是props,而且只能父组件传给子组件,如果子组件要传数据给父组件,只能先父组件传一个函数给子组件,子组件再调用该方法,把数据作为形参传给父组件,那考虑一个事情,兄弟间组件要如何传递数据呢?这就要引出下面这个消息订阅-发布机制

    工具库:PubSubJs

    下载:npm install pubsub-js --save

    使用:

    1. 先引入:import PubSub from “pubsub-js”
    2. 要接收数据方订阅:PubSub.subscribe('消息名',(data)=>{ console.log(data) })
    3. 传递数据方发布:PubSub.publish('消息名',data)

    九、React路由

    9.1 相关理解

    9.1.1.SPA理解

    • 单页面应用(single page web application SPA)
    • 整个页面只有一个完整的页面(html文件)
    • 点击页面的链接不会刷新页面,只会做页面的局部更新
    • 数据都需要通过ajax请求获取,并在前端异步展示

    9.1.2.路由的理解

    1、 什么是路由?

    • 一个路由就是一个映射关系
    • key永远为路径,value可能是function或者component

    2、 路由分类

    • 后端路由

      a )理解:后端路由的key还是路径,只不过value是上述说的function,这个在学习node和Express的时候应该看到过,如下图
      在这里插入图片描述
      b) 注册路由:router.get(path,function(req,res){…})
      c) 工作过程:当node接收到一个请求时,会根据请求路径去匹配对应的路由,然后调用对应路由中的函数来处理请求,返回响应数据

    • 前端路由

      a) 浏览器端路由,value是对应组件(component),用于展示页面内容
      b) 注册路由:
      c) 工作过程:当浏览器path变为/test时,当前路由组件就会变成Test组件

    9.2 react-router-dom

    9.2.1 理解

    • 它是react的一个插件库
    • 专门用来实现一个SPA单页面应用
    • 基于react的项目基本都用它

    9.2.2 常用API

    1、内置组件

    2、知识点

    • 路由的基本使用
      在这里插入图片描述

    • 路由组件和一般组件
      在这里插入图片描述

    • NavLink的使用
      在这里插入图片描述

    • Switch的使用
      在这里插入图片描述

    • 路由的模糊匹配和精准匹配
      在这里插入图片描述

    • Redirect的使用
      在这里插入图片描述

    • 嵌套路由
      在这里插入图片描述

    • 向路由组件传递参数
      在这里插入图片描述

    • 路由跳转的两种模式(push、replace)

    默认开启的是push模式,push模式就是说每次的点击跳转改变路径,都是往浏览器历史记录的栈中不断追加一条记录,然后你点回退按钮时,它会指向当前栈顶记录的前一条,replcae模式就是说替换掉当前的那条记录,然后你点回退的时候,就不会显示上次被替换掉的那条记录了,只会显示上上条记录,那要怎么设置为replace模式呢?直接在标签上添加一个replace属性即可

    • 编程式路由导航(不借助link或者navLink这种手动点触发路由跳转)

    就是借用history对象的api来操作路由的跳转、前进、后退

    在这里插入图片描述

    • withRouter的使用

    作用:它就是专门解决在一般组件中想要使用路由组件的那几个API的这个问题的,它接收一个一般组件,然后调用后,该一般组件身上也有了路由组件的history、match等属性

    如何使用:
    1、先引入import { withRouter} from "react-router-dom"
    2、定义一般组件class XX extends ...
    3、export default withRouter( XX )

    • BrowserRouter和HashRouter的区别
      在这里插入图片描述

    10、redux

    10.1 redux理解

    10.1.1 redux是什么?

    1. 它是专门做状态管理的js库,不是react插件库
    2. 它可以用在angular、vue、react等项目中,但与react配合用到最多
    3. 作用:集中式管理react应用中多个组件共享的状态

    10.1.2 什么情况下需要使用它

    1. 某个组件的状态需要让其他组件也能拿到
    2. 一个组件需要改变另一个组件的状态(通信)
    3. 总体原则:能不用就不用,如果不用比较吃力,就可以使用

    redux的工作流程
    在这里插入图片描述

    11、react-redux

    原先redux是独立公司创建的,后来react公司发现开发者都这么喜欢在react项目中使用redux,所以就自己开发了一个react的插件叫react-redux

    11.1、react-redux模型图

    在这里插入图片描述

    11.2、react-redux基本使用

    在这里插入图片描述

    11.2、纯函数

    在这里插入图片描述

    11.3、react-redux开发者工具

    1. 打开chrome网上商店,下载开发者工具Redux DevTools
    2. 下载完后右上方的插件图标还是不会亮的,因为它还识别不了你写的redux,所以还需要下载一个库(redux-devtools-extension)
    3. 然后再你的store文件中引入该库文件import {composeWithDevTools} from redux-devtools-extension
    4. 然后再createStore()的第二个参数位置调用composeWithDevTools(),将之前放在这个位置的中间件传到该方法中
      export default createStore(allReducer,composeWithDevTools(applyMiddleware(thunk)))

    12、项目打包运行

    在react脚手架中通过npm run start 来运行启动项目并打开页面,打包生成静态文件就要用到另一个命令(npm run build),它会生成一个build文件夹,一般这个生成的静态文件都是放到服务器上去运行的,那么问题来了,服务器要怎么搭建呢?

    方法一:用node+express可以搭建一个简单的服务器
    方法二:需要用到一个库serve,使用前需要先下载npm i serve -S,然后直接在对应文件夹中执行serve即可,比方在这里,当前文件路径是项目根目录,直接serve build即可,就可以开启一个5000端口的服务器了

    13、Hooks

    13.1、React Hook /Hooks是什么?

    1、Hook是React 16.8新推出的新特性/新语法
    2、可以让你在函数式组件中使用state或其他特性

    13.2、三个常用Hook

    1、React.useState()
    2、React.useEffect()
    3、React.useRef()

    13.3、useState

    在这里插入图片描述
    Demo:

    import React,{useState} from 'react';
    
    export default ()=>{
    
      //useState()中接收的是state的默认值,前面是数组解构,第一个是state变量,第二个是改变state的方法,类似于setState()
      const [count,setCount] =useState( 0 )
      	render(
      		
    {count}
    ) }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这里思考个问题,当你点击按钮+1时,状态改变的时候,整个函数组件就会执行,所以第四行也自然会执行,那它的状态不就又变成0了吗?还能正常+1吗?

    答案:是可以正常+1,为什么呢?因为这行代码底层做了处理,当状态改变重新调用整个函数组件时,这句话是会执行,但它不会去覆盖count值,所以count值还是会正常+1

    13.4、useEffect
    在这里插入图片描述

    总结:这个钩子函数相当于类组件三个钩子函数的集合,当你想用做componentDIdMount时,可以在第二个参数中加上[],表示谁都不监听,只会在第一次挂载时调用,这就相当于didMount函数了,如果你想当componentDidUpdate函数用,那么你可以在第二个参数加上你要监听更新的state值,注意是数组,如果你要当componentWillUnmount函数,则在useEffect()接收的第一个函数中返回一个函数,这个返回的函数就相当于willUnMount

    13.5、useRef
    在这里插入图片描述

    14、React扩展知识

    14.1、setState的两种写法在这里插入图片描述

    Demo:

    //这里我们先统一不考虑第二个参数回调
    
    对象式写法:
    const {count} =this.state;
    this.setState({ count:count+1})    //setState()方法接收一个对象
    
    函数式写法:
    this.setState((state,props)=>{    //函数式写法可以接收老的state和props数据
    	return {count:1}
    })
    简写:this.setState(state=>({count+state}))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    14.2、lazyload(懒加载)

    这里我们要讲的懒加载主要是针对路由组件的懒加载,就是你点击路由导航菜单,加载对应组件的时候懒加载,具体来看下面code。。。

    //原先的路由组件引入:
    import Demo1 from "./Demo1"
    import Demo2 from "./Demo2"
    
    
    
    
    //现在使用lazyload:
    import React,{component,lazy} from "react    // 需要用到react中的lazy函数
    
    // 引入路由组件方式通过调用lazy(),然后接收一个函数的方式,import 引入文件也可以通过函数调用的方式
    const Demo1 = lazy(()=>{import('./Demo1')})  
    const Demo2 = lazy(()=>{import('./Demo2')})  
    
    //路由配置那边也要改动,用Suspense标签包裹下,再传一个fallback属性,接收一个组件,你可以自定义一个加载过程中的简单组件,再资源没回来之前会显示这个传入的简单加载组件,就是为了再网速慢得情况下,页面不至于白屏,提高用户体验
    
    	
    	
    
    
    **注意:**这里引入得加载组件必须通过直接引入的方式import Loading from "./Loading"`
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    14.3、Fragment标签

    在这里插入图片描述

    简单一句话概括:这个标签就是用在有时页面结构层级太多,而且有些都是语法要求,实际没意义的结构层级(return()中的根节点就是这个情况),这时你就可以用Fragment标签,当然<>在一般情况下和Fragment标签作用相同,当时有一点不一样,就是Fragment标签能接收一个key属性,而<>什么属性都不能接收

    14.4、Context

    理解:这里说的Context其实就是类组件中实例对象中的一个属性,它和state、props、ref是同一级的;
    作用:它可以解决多层组件之间,祖先组件要往后代组件传递数据的情况,不用再一层一层的props传
    使用原理: 举个例子,要把父组件中state的值传递给孙子组件,那么在父组件的全局位置创建一个容器对象,然后用这个容器对象的Provider标签包裹父组件,同时传value={state数据},注意,这里的value字段名不能改,只能是value,然后孙子组件可以用下面的两种方式去接收数据

    在这里插入图片描述

    14.5、PureComponent(纯组件)

    在这里插入图片描述

    具体的使用:就是原先extends Component=》extends PureComponent 即可

    14.6、错误边界

    所谓的错误边界就是说,在实际开发过程中,组件复用是很正常的,但你很难避免调用的子组件出现错误(语法错误,或者是因为数据格式不对导致的报错,你不可能兼容到各个位置),如果没有错误边界,当子组件出现问题的时候,整个页面就都会挂掉,所以为了用户体验,让错误不影响整个页面,所以要用这个错误边界,注意:这个错误边界时要在父组件中进行处理的

    在这里插入图片描述

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    算法练习10——数组为空的最少操作次数
    算法刷题:经典TopK问题整理
    开源世界的学术问题
    雪花算法(snowflake)
    leetcode 903. DI 序列的有效排列
    Python学习笔记—基本语法
    关于ETL的两种架构(ETL架构和ELT架构)
    如何应对量化交易,个人股票账户如何实现量化程序化自动交易
    前端系列-1 HTML+JS+CSS基础
    面向对象编程原则(03)——单一职责原则
  • 原文地址:https://blog.csdn.net/m0_61083409/article/details/126113982