-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
升级 React 记录 #92
Comments
np |
@hongzzz |
🐮🍺 |
np |
1 similar comment
np |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
升级 React 版本 记录/文档
Why
React
目前最新的公开版本为16.7
,而 目前项目版本为15.5
。对比有如下重要变化:
新核心架构:Fiber (16.0)
异步渲染:周期性地对浏览器执行调度渲染工作的策略。
通过异步渲染,避免阻塞了主线程,实施更快地响应。
异步渲染能够将渲染任务划分为多块,这意味着几乎所有的行为都是同步发生的。
React 16.X 使用浏览器提供的 API 间歇性地检查当前是否还有其他任务需要完成,从而实现了对主线程和渲染过程的间接管理。
例如拖动、onChange等在不考虑防抖情况,以及频繁setState的场景,相对于之前版本,有一定性能的提升。
这意味着 React 可以在更细的粒度上控制组件的绘制过程,从最终的用户体验来讲,用户可以体验到更流畅交互及动画体验。而因为异步渲染涉及到 React 的方方面面甚至未来,在 16.0 版本中 React 还暂时没有启用
减少文件体积 (16.0)
React 16 对比 15.6.1
更好地 SSR (16.0)
What’s New With Server-Side Rendering in React 16 – Hacker Noon
Fragment (16.2)
我们编写组件常见模式是将一个组件返回多个元素。
为了包裹多个元素肯定写过的
div
或span
,为了不必要的嵌套,提出了Fragment
Fragments
与Vue.js
的<template>
功能类似,做不可见的包裹元素。Fragments简写形式
<></>
New LifeCycle (16.3)
官方团队在实现更好地SSR时发现有些现有的生命周期经常被开发者误用或者“巧妙”的使用,这些生命周期容易带来不好的实践。它们是:
componentWillMount
componentWillReceiveProps
componentWillUpdate
这三个生命周期将在 17.0 版本之前,启用⚠️
Strict Mode
下 console 警告并在17.0之后,必须加前缀
UNSAFE_
才能正常使用。未来版本将逐步去掉这三个生命周期。
React 16.3 一并带来了 两个新的生命周期:
static getDerivedStateFromProps
getSnapshotBeforeUpdate
static getDerivedStateFromProps
返回要更新的 state 内容,返回 null表示没有 state 需要更新(为差异化更新 state,与现有 setState 方式一致;与 React Hooks 方式不同)New Context API (16.3)
现有 Context API 一直被官方定义为实验性API,有许多问题:
违反目前React组件设计。无法将使用 context 的子组件无缝移植到其他的根组件树种
在 Context 值更新后,顶层组件向目标组件 的 props 透传过程中,如果中间过程的某个组件的
shouldComponentUpdate
返回了 false,所以无法触发之后子组件的 reRender,导致无法得到新的 Context 值而 新的 Context API 解决了以上的问题,并且采用声明式写法。小型复杂组件间适合采用 Context
React.memo (16.6)
类似于 Class 组件使用的
PureComponent
这是为
functional component
实现的过滤层,只有在 props 变化(浅比较)才会更新组件。Lazy (16.6)
Lazy
Suspense
用来添加一个 placeholder,在 lazy 化 component 加载之前显示fallback 是懒加载组件载入过程中的一个过渡,可以放一些过渡效果或方法。
Strict Mode (16.6)
Strict Mode – React
Hooks
重点!
好吧,目前 16.7 还不能用,但未来几个月就可以用上这一突破功能。
有关文档:Introducing Hooks – React
How
升级 react 包
选择升级的 npm 包
react
react-dom
以及重点选择了几个有关react的包
替换生命周期
总览: LifeCycle 变更
componentWillMount
componentWillUpdate
componentWillReceiveProps
static getDerivedStateFromProps
getSnapshotBeforeUpdate
实施
componentWillMount
——>componentDidMount
无痛变更
componentWillMount
存在的 问题:componentWillUpdate
——>componentDidUpdate
无痛变更
与
componentWillMount
存在的问题差不多,也可能会多次执行componentWillReceiveProps ——> static getDerivedStateFromProps + componentDidUpdate
这个可能是修改起来比较麻烦的一个了,项目中使用的机会比较多,一般用作:
Props
变更与否来修改State
Props
改变时去调用一些Func
,或者做出一些不会修改state
的操作针对第一种,更换方法:
componentWillReceiveProps
——>getDerivedStateFromProp
返回需要更新的state(差异化更新,与现有 setState 方式一致,与 Hooks 不同)
或是 null :表示state不需要更新
通过例子:
以往我们依赖比较
this.props.xxx
与nextProps.xxx
或者nextProps.xxx
与this.state.xxx
是不行了。在
getDerivedStateFromProps
中,需要将要比较的值也存到state当中,才能在之后通过 第二个参数prevState
进行比较,比如nextProps.xxx vs prevState.xxx
针对第二种,使用
compomentDidUpdate
:基于
getDerivedStateFromProp
的执行次数不可预测性,以及静态方法。所有需要执行的
side-effects
要放在compomentDidUpdate
中去执行基本上在旧有
componentWillReceiveProps
中没有更新state
的情况下,使用这个 methods 来代替是完全可行的,因为包括了我们需要用的到prevProps
,并且componentDidUpdate
内部可以访问this.props
,利用这两个我们可以作出对应比较在 16.4 修复了 16.3 版本关于
getDerivedStateFromProps
调用的时机,加入了 组件自身触发setState
以及forceUpate
getSnapshotBeforeUpdate
很少情况会用到。
将在 DOM 被更新前调用,此生命周期的返回值将作为第三个参数传递给
componentDidUpdate
Context 替换
暂无替换,鉴于项目内使用到的地方比较杂,旧 Context API 方法在 17.0 之前还是可以正常使用
Pains
升级遇到的痛点
componentWillReceiveProps
异步延时调用 setState …… ,而getDerivedStateFromProps
中无法 异步更新state
,所以做了大量工作去优化重写,实在优化不了的在DidUpdate
去调用setState
(会造成多次渲染,但组件树不复杂的情况,忽略这些开销)有很多子组件
state
初始值依赖于父组件,但却是在componentWillReceiveProps
方法中 去初始化,之后子组件setState
替换掉state
值。由于子组件setState
不会调用componentWillReceiveProps
,但会调用getDerivedStateFromProps
,导致更新state
值无效。解决:修改逻辑,加状态锁
之前很多逻辑只依赖于
componentWillReceiveProps
,现在用getDerivedStateFromProps
同componentDidUpdate
去替换,导致逻辑分层,有些相似的逻辑要重复写(并不是说这里可以写个方法来重用,只是多了很多不必要的相似逻辑)有些组件的逻辑 严重依赖
componentWillReceiveProps
,而getDerivedStateFromProps
在mounting
阶段也会调用,需要根据具体情况修改逻辑…basicPopup
组件……此组件在
submodule
,由于修改此组件,需要配合修改所有继承自它的Popup
组件,而 这些组件并不全部在teachingSite
。也就是说,如果修改它,必须将依赖于它的所有项目升级 react 版本至 16.4 及其以上。暂时放弃此组件及其子类组件。(备注:在17.0之前,过去的生命周期可正常使用)Regret
componentWillReceiveProps
The text was updated successfully, but these errors were encountered: