react的基础与实践
01 react简介与特性
官网解释:用于构建用户界面的js库
我的解释:主要是构建和操作视图
特点:声明式 (只用关注结果)setsatate (区别于命令式编程,需要一步步告诉机器)
组件化 把页面拆分成多个组件
跨平台编写
react lazy:通过对组件进行分割打包成多个chunk来减少一次性加载的资源大小
这样在打包代码时,可以显著减少主包的体积,加快加载速度,从而提升用户体验;而当路由切换时,加载新的组件代码,代码加载是异步的过程,此时suspense就会进如fallback,那我们看到的就是loading,显式的告诉用户正在加载,当代码加载完成就会展示A组件的内容,整个loading状态不用开发者去控制。
问题一:资源网络慢,怎么办呢:采用lazy 和 suspense
点到了路由,才开始加载点到的组件
问题二:网络崩溃了,资源来不下来
errorboundary 出现错误的时候渲染降级ui
现在只能在类组件使用
react 更新流程
虚拟dom本质就是一个js对象,渲染器可以生成真实dom
需要通过渲染器在调用render和setstate时,首先是协调器收到更新请求updatacontainer,在将更新任务交给调度器分成多个时间切片任务,在浏览器的空闲时间再进行优先级调度,找到比较高优的任务,传给调用协调器的回调函数,再进行由上至下的递归比较,再更新fiber树,在所有更新任务结束以后再将这个fiber树交给渲染器渲染。
怎么进行fiber树比较的呢:在内存有两颗fiber树,一棵是现有的fiber树,另一个是正在构建的fiber树
通过alternate这个属性,可以将两棵树的同级节点关联起来
需要学习状态管理:Redux 路由工具:react router
JSX 转换成 js 需要babel
类组件
例子:
类组件的定时器,挂载的时候再去清除这个定时器
四个需要注意的点:
1.首先需要去继承这个react.component的基类
2.在构造函数里调用一下父组件的构造函数 super(props)
3.this的使用,想要保存一些常量变量也是在this上面
4.生命周期:在组件挂载,取消卸载之前要做一些操作
5.render方法,render作为组件操作必须要写render方法,并且返回一个jsx组件
函数式组件
hook是16.8的新特性,可以直接带入setdate
hook的规则
1.只能在最顶层用hook
hook类似电子,组件是原子,可以直接渲染到页面上
第一次渲染时,链表的2索引是useeffect,第二次渲染时则应是usestate,但是react不知道返回的是什么,每一次的hook都被提前调用了一次,这个时候浏览器页面就会报错
应该这样更改:
2.只能在react函数中调用hook
自定义hook是逻辑复用的机制,每次使用时state和effect完全隔离
右边的第一板块,在自定义hook中,只有依赖变化的时候,第一次调的时候不会操作,第二次调才懂
hook过期闭包问题
过期闭包的两个要点:
1,套一层函数,创建多一层作用域。
2,在新创建的作用域中,要捕捉上层作用域中改变的值
for (var i=0;i<3;i++){
(function(){
let j = i;
setTimeout(function handler(){ console.log(j)}, 1000);
})();
}
在右边的react中为防止过期闭包,加入了依赖数组
02 react 常见的api与作用
03具体场景案例
从页面布局拆分成四个
从页面拆分成五个
从组件的维度拆分
父组件给子组件通信
如果表单控件有20个元素,给子组件都加上size这个属性
利用cloneelement这个api,给所有子节点加上一些公共的props
将props.size属性传入到commonprops,将这个额外属性传递到child上
子组件给父组件通信
表单的组件:
将按钮change和clear放到外层,但方法是在内层
解决方法:外层给子组件传递一个对象,将方法传到对象里,ref转发
代码:
下划线的,给ref添加change,clear方法
利用fowardRef再转发给上层组件
组件间共享信息
登录登出都是在Navbar,拿到用户信息之后功能都是在main content操作
但是要共享用户信息,Navbar与main同步更新
UseInfo与Navbar,都是某个组件的子组件,通过useContext去读到globalcontext这个共享的信息
通过usereducer去更新,删除globalcontext这个共享库
首先定义reducer这个操作库,set即使我传了什么用户信息就返回什么,update就是把原来的状态留着,在更新新的,remove就是传一个undefined,默认就是一个读的操作,返回文档里的信息。
创建一个公共容器实现信息共享store
右侧的子件globalcontext.providerdispatch是方法,state是值。
在Navbar的组件读到了user,登录里面,类型是set传一个use传给公共容器
没有hook的时候是怎么进行组件的信息共享呢
是将state和dispatch注入到globalcontext里面
在index.jsx种直接传store下去,在具体组件里面用react—redux中的connect
组件优化案例
wrapper是最外层的组件父组件,count是给子组件用的 name是个父组件自己用的,计算的操作计算一个数组遍历。
increment是给数+1
父组件渲染了,子组件不管变不变都也跟着渲染了
在类组件里面如果count没有变,那么只要用shouldcomponent return first就行;在hook里面用的是react.memo包一下这个组件就行
increment第一次渲染和第二次渲染都定义了一边,但是在内存里面不完全相等
usecallback返回的是不会次次重新定义的函数,只要依赖项count不变就不会重新定义
usememo返回的是不会次次重新计算的值,只要依赖项count不变就不会计算
组件挂载位置
button写在蓝色容器下面,但是真实dom渲染在黄色下面
用react-dom中createPortal将子节点渲染到存在于父组件以外 DOM 节点的方案,传了一个color一个contain,传了一个已经挂载的容器里面,那就把组件传到这里
冒泡问题
当点击了hide,因为冒泡会到外层再show
这个时候要在hide 的button外再加一层div
这里再考虑potral的冒泡,渲染的时候都是虚拟dom
如何进行逻辑复用
最左边是入参,