React16 版本解决了哪些问题,加了哪些东西
上期回顾:
React 项目有哪些优化点
- 保证数据的不可变性
- 使用唯一的键值迭代
- 使用 webWork 做密集型输出
- 不在 render 中处理数据
- 不必要的标签,使用 React.Fragments
- 对于 CSR 或 SSR,都使用 Service worker 来资源调配及骨架图,CSR 用懒加载,SSR 服务端用 stream 流处理
- 尽可能把 FCP 提前
- 使用 React.Profiler 分析渲染的一些任务
- 使用 PureComponent 及 React.memo 等做浅对比,用 ShouldComponentUpdate 做深比较。
- 尽量减少 render,使用 React.useMemo 与 React.useCallback 做数据优化
- 为保证应用的可用性,使用 componentDidCatch 来处理
今日解答:
一,React16 废弃的生命周期和新的生命周期
- React16 废弃的三个生命周期有 3 个 will:
componentWillMount
,
componentWillReceiveProps
,
componentWillUpdate
。
废弃的原因是,在 React16 的 Fiber 架构中,调和过程会多次执行 will 周期,不再是一次执行,失去了原有的意义,此外,多次执行,在生命周期中如果有 setState 活 dom 操作,会触发多次重绘,影响性能,也会导致数据错乱。
componentWillReceiveProps
- i. 在 props 变化时触发
- ii. 在父组件导致子组件的 rerender 时,即使 props 没有变化,也触发【componentWillReceiveProps 的设计本身就存在问题】
- Reactt16 的新增的两个生命周期
getDerivedStateFromProps
,
getSnapshotBeforeUpdate
getDerivedStateFromProps
的用法
- 触发频繁,无论 state 还是 props 变化,都会触发
- 不能 setState,而是返回一个对象来更新 state,使用不便,也可能触发多次状态更新
getSnapshotBeforeUpdate
- 在 render 之后,更新 dom 之前,state 已更新,可以用来读取 dom,强制用户只能在 mount 阶段读取 dom
- getSnapshotBeforeUpdate 这个周期在 Fiber 架构中,只会调用一次,实现了类似 willMount 的效果
二:React16 的三大特性
- TimeSlicing【时间切片】
- 为解决 CPU 速度问题,React 在 render 的时候,不会阻塞现在的线程
- 简单来说,react 的异步渲染其实是拉长了 render 的时间,一次跑一点,所以机器性能很差的时候,react 渲染只会有稍微的延迟,而不是卡顿
- Suspense 【悬停】
- 主要解决网络的 IO 问题
调用render函数->发现有异步请求->悬停,等待异步请求结果->再渲染展示数据
- 添加了 componentDidCatch,可以友好的展示 fallback 组件,可以捕捉到它的子元素(包括嵌套子元素)抛出的异常;可以复用错误组件。
React16.8
- 加入 hooks,让 react 函数式组件更加灵活
- hooks 之前,React 存在很多问题
- a. 组件间复用状态逻辑困难
- b. 复杂组件难以理解,高阶组件和函数组件的嵌套过深
- c. class 组件的 this 指向问题
- d. 难以记忆的生命周期
- 常用的 hooks
- useState 返回有状态的值,以及更新这个状态值的函数
- useEffect 接受包含命令式,可能有副作用代码的函数
- useContext 接受上下文对象(从 React.createContext 返回的值),并返回当前上下文值
- useReducer userState 的替代方案,接受类型为(state, action)=> newState 的 reducer,并返回 dispatch 方配对当前状态
- useCallback, 返回一个回忆的 memoized 版本
- useMemo 纯的记忆函数
- useRef 返回一个可变的 ref 对象,其.current 属性被初始化为传递的参数,返回的 ref 对象在组件的整个生命周期内保持不变
- useImperativeMethods 自定义使用 ref 时公开给父组件的实例值
- useMutationEffect 更新兄弟组件之前,它在 React 执行其 DOM 改变的同一阶段同步触发
- useLayoutEffect Dom 改变后同步触发,使用它来从 DOM 读取布局并同步重新渲染
react16.9
- 重命名 Unsafe 生命周期,改为 UNSAFE_
- 废弃
javascript:
形式的 URL,以JavaScript:
开头的 URL 容易遭受攻击,造成安全漏洞
- 废弃 Factory 组件
- act()支持异步函数,可以在调用它的时候使用 await
<React.Profiler>
进行性能评估
React16.13.0
- 支持在渲染期间调用 setState,但仅适用于同一组件
- 可检测冲突的样式规则并记录警告
- 废弃 unstatble_createPortal,并使用 createPortal
- 将组件堆栈添加到开发警告中,使开发人员能够隔离 bug 并进行调试程序