1. react 虚拟DOM
- 将代码转换成JS对象,然后由JS对象转换成真实DOM
- 如果是首次渲染,其实vitruaDom不具有任何优势,甚至更加消耗内存,但是它的优势在于diff算法和批量处理策略
- react基于virtialdom自己实现了一套事件机制自己模拟事件冒泡,捕获,采用事件代理,批量更新,解决兼容性问题,它将virtualdom上的事件映射到真实的Dom事件,然后将所有的事件都代理到document上,进行统一分发
- react.createElement 将 props,children , 进行批量处理,传递给reactElement
- $$typeof 是一个symbol类型的变量,可以防止xss攻击,由于json中是不能存储symbol对象的
(xss:它是通过对网页注入可执行代码且成功地被浏览器 执行,达到攻击的目的)
2. react 渲染流程
- 使用react.createElement /JSX 编写文件最后都会通过babel转换成 createElement
- createElement 对key和ref等props做了处理,获取defaultProps对默认props进行复制,对传入的子节点处理,最后形成虚拟dom
- reactdom.render将生成好的虚拟dom渲染指定容器上,然后采用了批量处理,事务机制等对指定浏览器进行性能优化,最后转换成DOM
3.setstate
调用setstate不用立即更新
setstate本身不是异步的,只是在调用setstate的时候,如果react处于更新状态。当前更新会暂停,等上一次更新执行后在执行
BH4JE_KPRLTQ@6RFS{`XG6A.png
4. bind(this)
- 由于在调用事件过程中并没有指定调用的组件所以需要手动绑定,否则this = undefined
- 箭头函数不会创建自己的this,它只会从自己作用域上一层继承this
5. react事件执行顺序
1.由于react的所有事件都是挂载到document上的,当真实的dom触发冒泡,到document后才会对react事件进行处理
- 先执行原生的事件
- 然后执行react合成事件
- 最后执行真正在document上挂载的事件
6. mixin , hook, hoc
- mixin:混入
将一个对象的属性拷贝到另一个对象上,可以是多个,也可以是一个,这是extends无法实现的。
缺点:1. mixin 可能会相互依赖,相互耦合,不利于后期的维护,2. 不同的mixin中的方法会冲突 - hoc
- 渲染劫持
- 操作props / state ,获取refs
- 状态管理
hoc实现功能 - 通过原组件和其他组件进行组合渲染可以达到样式布局复用
- 属性代理
- 反向代理 -- super.render()
- 根据特定属性觉得原组件是否渲染
基本用途: 日志打点 / 权限控制 / 实现双向绑定(利用hoc 代理onchange方法和value属性)/ 表单校验 。。。
- 实例:
redux中的connect其实就是将mapStateTOProps 和 mapDispatchToProps分别解构后传递给原组件,这样就可以在原组件内直接通过props获取到state和dispatch函数 - 优点
高级组件时一个没有副作用的纯函数,各个高阶组件不会互相依赖耦合
高阶组件并不关心数据使用的方式和原因,而被包裹的组件也不关心数据的来源 - 缺点
hoc可以劫持props ,在不遵守约定的情况下会造成冲突
如果大量使用,对调试会由很多困难由于多层嵌套
- hooks
只能在函数式中使用
- 优势:
减少状态逻辑复用的风险
避免地狱式嵌套
使用函数代替class
7. redux
- redux的可预测性:1. 单一的数据源,应用只能有一个store. 2. 所有数据都是只读的,要想更新数据,必须dispatch一个action来更新3. 当处理action的时候,不得直接修改原始对象必须生成一个新的state
- reducer是纯函数:同样的输入必定得到同样的输出,就可以保证同样的state就一定得到童话贵阳的view,所以reducer里不能改变state,只能返回一个权限的state对象
- redux设计思想:web应用是一个状态机制,视图和状态是一一对应的。所有的状态,保存在一个对象里面。
- Redux是如何将state注入到React组件上的: provider组件,将store传递给provider,通过connect接受、state和mapDispatchToProps
8. react新特性
- Error Bounday
如果组件发生错误,可以通过error boundary捕获优雅处理 配合使用了以恶新生命周期 componentDidCatch - render新增了返回的值类型:支持string / number / boolean / null / portal /fragment
- portals可以把组件渲染到当前组件之外,多用于弹框之类的
- setstate传入null就不会发生更新
- 更好的服务器渲染 ,由于15的三倍
- 采用了新的核心架构,fiber 将原来的同步更新转变成更新过程碎片化,避免长时间阻塞主线程使得应用渲染更加流畅
- 支持自定义dom
- 减少文件体积,从 161.7kb -> 109kb
- call return (react-call-return npm)
解决了父组件需要跟据子组件的回调信息去渲染子组件 - fragment
将一些子元素添加到dom tree,不需要为这些元素提供额外的父节点 - createRef / forwardRef
通过createRef获取red对象 forwardRef是ref的转发可以让父组件获得子组件的ref,从而操作子组件 - 生命周期更新
增加了getDerivedStateFromProps(nextprops,prestate)
9. diff算法
在调用react renderd 的时候,会创建react元素组成的树,在下一次,state和props更新的时候,相同的render会返回不同的树,就需要不叫这两棵树的差别,常规操作一般需要的算法的复杂度o(n^3),但是一旦元素过多则会开销过大,造成页面卡顿,所以,react提出了两个假设:
- 两个不停类型的元素会产生不同的树
- 开发者可以通过key,props来暗示哪些子元素在不同的渲染下保持稳定
这样算法的复杂度就是o(n)
可以分为: tree diff / component diff /element diff
- tree diff
react为了让运行效率更高,tree diff只对树进行同层对比,不去比较跨层的节点。 - component diff
同一层只要出现不是同一类型的组件,就替换该组件的所有子节点。 - element diff
主要是根据mountIndex和lastIndex进行比较,在确定是否移动 ,
https://segmentfault.com/a/1190000010686582
网友评论