react的基础与实践 | 青训营笔记

67 阅读10分钟

react的基础与实践

01 react简介与特性

官网解释:用于构建用户界面的js库

我的解释:主要是构建和操作视图

特点:声明式 (只用关注结果)setsatate (区别于命令式编程,需要一步步告诉机器)

​ 组件化 把页面拆分成多个组件

​ 跨平台编写

image-20230430111536616

react lazy:通过对组件进行分割打包成多个chunk来减少一次性加载的资源大小

这样在打包代码时,可以显著减少主包的体积,加快加载速度,从而提升用户体验;而当路由切换时,加载新的组件代码,代码加载是异步的过程,此时suspense就会进如fallback,那我们看到的就是loading,显式的告诉用户正在加载,当代码加载完成就会展示A组件的内容,整个loading状态不用开发者去控制。

问题一:资源网络慢,怎么办呢:采用lazysuspense

点到了路由,才开始加载点到的组件

image-20230430112051748

image-20230430112021633

问题二:网络崩溃了,资源来不下来

errorboundary 出现错误的时候渲染降级ui

现在只能在类组件使用

image-20230430112943710

react 更新流程

image-20230502143122612

​ 虚拟dom本质就是一个js对象,渲染器可以生成真实dom

​ 需要通过渲染器在调用render和setstate时,首先是协调器收到更新请求updatacontainer,在将更新任务交给调度器分成多个时间切片任务,在浏览器的空闲时间再进行优先级调度,找到比较高优的任务,传给调用协调器的回调函数,再进行由上至下的递归比较,再更新fiber树,在所有更新任务结束以后再将这个fiber树交给渲染器渲染。

image-20230502144556442

怎么进行fiber树比较的呢:在内存有两颗fiber树,一棵是现有的fiber树,另一个是正在构建的fiber树

通过alternate这个属性,可以将两棵树的同级节点关联起来

image-20230502150000114

需要学习状态管理:Redux 路由工具:react router

JSX 转换成 js 需要babel

image-20230502150439580

类组件

image-20230502150506836

例子:

​ 类组件的定时器,挂载的时候再去清除这个定时器

​ 四个需要注意的点:

1.首先需要去继承这个react.component的基类

2.在构造函数里调用一下父组件的构造函数 super(props)

3.this的使用,想要保存一些常量变量也是在this上面

4.生命周期:在组件挂载,取消卸载之前要做一些操作

5.render方法,render作为组件操作必须要写render方法,并且返回一个jsx组件

image-20230502170013752

函数式组件

image-20230502211020640

hook是16.8的新特性,可以直接带入setdate

image-20230502231846637

hook的规则

1.只能在最顶层用hook

hook类似电子,组件是原子,可以直接渲染到页面上

image-20230502232248817

第一次渲染时,链表的2索引是useeffect,第二次渲染时则应是usestate,但是react不知道返回的是什么,每一次的hook都被提前调用了一次,这个时候浏览器页面就会报错

应该这样更改:

image-20230503105656267

2.只能在react函数中调用hook

image-20230503110906621

自定义hook是逻辑复用的机制,每次使用时state和effect完全隔离

右边的第一板块,在自定义hook中,只有依赖变化的时候,第一次调的时候不会操作,第二次调才懂

hook过期闭包问题

image-20230503115944035

过期闭包的两个要点:

1,套一层函数,创建多一层作用域。

2,在新创建的作用域中,要捕捉上层作用域中改变的值

for (var i=0;i<3;i++){
    (function(){
        let j = i;
        setTimeout(function handler(){ console.log(j)}, 1000);
    })();
}

在右边的react中为防止过期闭包,加入了依赖数组

image-20230503164453539

02 react 常见的api与作用

image-20230503164533690

image-20230503164558420

03具体场景案例

从页面布局拆分成四个

image-20230503165106727

从页面拆分成五个

image-20230503165159600

从组件的维度拆分

image-20230503165300645

父组件给子组件通信

如果表单控件有20个元素,给子组件都加上size这个属性

利用cloneelement这个api,给所有子节点加上一些公共的props

image-20230503172745164

将props.size属性传入到commonprops,将这个额外属性传递到child上

image-20230503172754201

子组件给父组件通信

表单的组件:

将按钮change和clear放到外层,但方法是在内层

解决方法:外层给子组件传递一个对象,将方法传到对象里,ref转发

image-20230503185630072

代码:

下划线的,给ref添加change,clear方法

利用fowardRef再转发给上层组件

image-20230503185852273

组件间共享信息

登录登出都是在Navbar,拿到用户信息之后功能都是在main content操作

但是要共享用户信息,Navbar与main同步更新

image-20230504164028202

UseInfo与Navbar,都是某个组件的子组件,通过useContext去读到globalcontext这个共享的信息

通过usereducer去更新,删除globalcontext这个共享库

image-20230504164121399

image-20230504165412905

首先定义reducer这个操作库,set即使我传了什么用户信息就返回什么,update就是把原来的状态留着,在更新新的,remove就是传一个undefined,默认就是一个读的操作,返回文档里的信息。

创建一个公共容器实现信息共享store

右侧的子件globalcontext.providerdispatch是方法,state是值。

在Navbar的组件读到了user,登录里面,类型是set传一个use传给公共容器image-20230504215003290

没有hook的时候是怎么进行组件的信息共享呢

是将state和dispatch注入到globalcontext里面

image-20230504215212114

在index.jsx种直接传store下去,在具体组件里面用react—redux中的connect

image-20230504215420672

组件优化案例

image-20230504225704328

wrapper是最外层的组件父组件,count是给子组件用的 name是个父组件自己用的,计算的操作计算一个数组遍历。

image-20230504230007147

increment是给数+1

父组件渲染了,子组件不管变不变都也跟着渲染了

image-20230504230352844

在类组件里面如果count没有变,那么只要用shouldcomponent return first就行;在hook里面用的是react.memo包一下这个组件就行

image-20230504230531513

increment第一次渲染和第二次渲染都定义了一边,但是在内存里面不完全相等

usecallback返回的是不会次次重新定义的函数,只要依赖项count不变就不会重新定义

usememo返回的是不会次次重新计算的值,只要依赖项count不变就不会计算

组件挂载位置

image-20230504235249084

image-20230504235425300

button写在蓝色容器下面,但是真实dom渲染在黄色下面

用react-dom中createPortal将子节点渲染到存在于父组件以外 DOM 节点的方案,传了一个color一个contain,传了一个已经挂载的容器里面,那就把组件传到这里

image-20230504235507404

冒泡问题

当点击了hide,因为冒泡会到外层再show

这个时候要在hide 的button外再加一层div

image-20230505000522337

这里再考虑potral的冒泡,渲染的时候都是虚拟dom

image-20230505000909489

如何进行逻辑复用

image-20230505001151099

image-20230505001239551

最左边是入参,

image-20230505001515415