一 目录
不折腾的前端,和咸鱼有什么区别
二 前言
React 是现如今流行的前端框架,也是很多大厂面试必备。
React 与 Vue 虽有不同,但同样作为一款 MV*
框架,虽然实现可能不一样,但在一些理念上还是有相似的,例如数据驱动、组件化、虚拟 DOM 等。
当然,还有一些问题,可能最近都没法搞清楚的了,毕竟罗马不是一天能建成的:
- React 的实现原理?有什么优缺点?
这些往往要更深入挖掘方可得知自己的结论,任重道远,不停歇。
三 知识点
- 前端历史演进
- React 和原生对比
- 组件化
- 天然分层
- 生态好
- 开发效率
- React 和 Vue 对比
- 相同之处:虚拟 DOM、组件化、构建工具、配套框架、Chrome 开发工具
- 不同之处:模板 和 JSX、监听数据变化方式不同、Diff 不同
- React Fiber
- React 生命周期
- 挂载阶段:
constructor
、getDerivedStateFromProps
、render
、componentDidMount
- 更新阶段:
getDerivedStateFromProps
、shouldComponentUpdate
、render
、getSnapshotBeforeUpdate
、componentDidUpdate
- 卸载阶段:
componentWillUnmount
- 挂载阶段:
-
setState
- 调用之后发生什么
- 同步还是异步
- this 指向问题
- 通过
bind
修正 - 通过箭头函数修正
-
bind
和箭头函数的区别
- 通过
- 受控组件和非受控组件:
value
和defaultValue
- 组件通讯
-
props
-
Context
-
Redux
-
-
Redux
:Redux
、React-Redux
以及Redux-Saga
工作流 -
Mixin
、HOC
和Hook
- 性能优化
- 首屏渲染优化
prerender-spa-plugin
- 页面占位
react-placeholder
- 页面切换优化
html-webpack-plugin
- 减少业务体积代码
Tree Shaking
- 提取公共代码
SplitChunkPlugin
- 切分代码
Code Splitting
- 懒加载
react-lazyload
- 首屏渲染优化
四 前端历史演进
- jQuery 时代
通过 Ajax
从后端获取数据,然后通过 jQuery 生成 DOM 结果更新到页面中。
但是随着业务发展,项目越来越复杂,交互性越来越强,往往用户在某个时刻可能操作好几块内容,从而 DOM 的操作越来越频繁,页面性能逐步降低,用户也不满意这样卡慢的现状了。
- MVVM
这时候有了 MVVM,双向数据绑定让数据在修改的时候同步 DOM 的更新,反之亦可。
这个设定大大降低手动维护 DOM 的成本,而 MVVM 为 React 的特性之一,虽然 React 属于单项数据流,需要我们手动实现双向数据绑定。
- 虚拟 DOM
光靠绑定是不够的,这样没法解决频繁操作 DOM 的问题。
所以 React 内部实现了一套虚拟 DOM 的更新,它将真实 DOM 在 JS 中做一套缓存,每次有数据更新的时候,先内部通过 Diff
算法进行比对,然后收集一箩筐更新后,才对 DOM 进行更新,这样就大大降低了 DOM 的操作次数。
- Diff 运作
那么,Diff
怎么运作呢?
Diff
获取虚拟 DOM 节点变更的 4 种情况比较:节点类型变了、节点类型一样,仅仅属性或者属性值变了、文本变了、增加、删除或者移动了子节点。
- setState
React 不同于 Vue,可以通过 v-model
的形式,让用户的操作和 JavaScript 存储的数据同步更新,它需要通过 setState
来更新组件内容。
- Redux
但是,如果想通过一个组件来渲染它兄弟组件,React 一开始在这块做得并不是那么好,所以就需要引入一个状态管理中心,来帮助我们管理状态(state
),因而就有了 Redux
。
在 Redux
中,当 state
有变化的时候,依赖这个 state
的组件就会重新渲染,这样就解决了组件间数据传递的问题。
- Mobx
Redux
有个问题,就是修改某个 state
的时候,需要经过 action.js
、types.js
、reducers.js
这一系列文件,这样子 Redux
的数据流虽然非常正规,但是写起来复杂啊。
所以,社区又出现了另一套解决方案,也就是 Mobx
。
Mobx
推崇代码简约移动,只需要定义一个可贯彻的对象,然后在哪个组件中使用到了这个可观察对象,并且这个对象的数据有更改,那就会重新渲染,这使得 Mobx
开发项目的时候可以简单快速地完成很多功能。
但是 Mobx
也有缺点,就是数据流太过随意,出了 Bug 不好定位。
- End
所以,针对于小项目来说,社区推荐使用 MobX,对大项目推荐使用 Redux。
本段文本参考的内容已记录在参考文献中
五 React 相比原生的好处
- 组件化: 其中以 React 的组件化最为彻底,甚至可以到函数级别的原子组件,高度的组件化可以是我们的工程易于维护、易于组合拓展。
- 天然分层: JQuery 时代的代码大部分情况下是面条代码,耦合严重,现代框架不管是 MVC、MVP 还是 MVVM 模式都能帮助我们进行分层,代码解耦更易于读写。
- 生态: 现在主流前端框架都自带生态,不管是数据流管理架构还是 UI 库都有成熟的解决方案。
- 开发效率: 现代前端框架都默认自动更新 DOM,而非我们手动操作,解放了开发者的手动 DOM 成本,提高开发效率,从根本上解决了 UI 与状态同步问题.
六 React 和 Vue 比对
6.1 相同之处
- 虚拟 DOM。映射真实 DOM,通过新旧 DOM 的 diff 对比,更好的跟踪渲染页面。
- 组件化。将应用拆分成一个个功能明确的模块,每个模块之间可以通过合适的方式互相联系。
- 构建工具。都有自己的构建工具,通过
Webpack
+Babel
去搭建脚手架。 - Chrome 开发工具。两者都有很好的 Chrome 扩展去帮助查找 Bug。
- 配套框架。Vue 有
Vue-router
和Vuex
,而 React 有React-router
和React-Redux
。
6.2 不同之处
- 模板 VS JSX。Vue 推荐编写近似常规
HTML
的模板进行渲染,而 React 推荐 JSX 的书写方式。 - 监听数据变化的不同。Vue 使用的是可变数据,而 React 更强调数据的不可变。在 Vue 中通过
v-model
绑定的数据,用户改变输入值后对应的值也相应改变。而 React 需要通过setState
进行设置变化。 - Diff 不同。Vue 通过双向链表实现边对比边更新 DOM,而 React 通过
Diff
队列保存需要更新的 DOM,得到patch
树,再统一批量更新 DOM。 - 开发团队。Vue 一开始核心就是 Evan You,后面再招了其他人组成团队;React 的话是一开始就是 Facebook 团队搞的。所以网上的人比对源码情况的话,Vue 的比 React 的简单易懂点。
实话实说是看别人说的异同,担心有 “小伙伴” 有自己观点,然后在这里被喷,jsliang 不敢持有任何自己的观点,但是面试我总是要这么回答面试官的 /滑稽
七 React Fiber
React 的核心流程可以分为两个部分:
reconciliation
(调度算法,也可称为render
):- 更新
state
与props
- 调用生命周期钩子
- 生成虚拟 DOM
- 通过新旧 VDOM 进行
diff
算法,获取 VDOMchange
- 确定是否需要重新渲染
- 更新
commit
- 如需要,则操作 DOM 节点更新;
为什么需要 Fiber
?
随着应用变得越来越庞大,整个更新渲染的过程开始变得吃力,大量的组件渲染会导致主进程长时间被占用,导致一些动画或高频操作出现卡顿和掉帧的情况。
而关键点,便是 同步阻塞。
在之前的调度算法中,React 需要实例化每个类组件,生成一颗组件树,使用 同步递归 的方式进行遍历渲染,而这个过程最大的问题就是无法 暂停和恢复。
所以,为了解决这个问题(同步阻塞),通常有两种方法: 异步 与 任务分割。
而 React Fiber
便是为了实现任务分割而诞生的。
React Fiber
简述:
- 在 React 16 版本中将调度算法进行了重构, 将之前的
stack reconciler
重构成新版的fiber reconciler
,变成了具有链表和指针的 单链表树遍历算法。通过指针映射,每个单元都记录着遍历当下的上一步与下一步,从而使遍历变得可以被暂停和重启。 - 可以理解为是一种 任务分割调度算法,主要是将原先同步更新渲染的任务分割成一个个独立的 小任务单位,根据不同的优先级,将小任务分散到浏览器的空闲时间执行,充分利用主进程的事件循环机制。
React Fiber
核心:
- 可以具象为一个数据结构
- 链表树遍历算法
- 任务分割
- 分散执行
- 优先级策略
八 React 生命周期
React 逐渐废弃的生命周期方法:
componentWillMount
componentWillReceiveProps
componentWillUpdate
8.1 版本 之前
8.2 版本 之后
8.2.1 挂载阶段
constructor
:构造函数,最先被执行,通常在构造函数中初始化state
对象或者给自定义方法绑定this
getDerivedStateFromProps
:static getDerivedStateFromProps(nextProps, prevState)
,这是个静态方法,当我们接收到新的属性想去修改我们state
,可以使用getDerivedStateFromProps
。render
:render
函数是个纯函数,只返回需要渲染的东西,不应该包含其他的业务逻辑,可以返回原生 DOM、React 组件、Fragment
、Portals
、字符串和数字等内容。componentDidMount
:组件装载之后调用,此时我们可以获取到 DOM 节点并操作,比如对Canvas
、SVG
等操作。服务器请求、订阅都可以写这个里面,但是记得在componentWillUnmount
中取消订阅。
React 的接口请求是放在 componentDidMount
里面比较合适,旧版本有人放在 componentWillMount
里面,从而导致多次请求,现在 componentWillMount
不推荐使用了,所以转 componentDidMount
就非常科学了。
存在以下问题:
- 为什么
getDerivedStateFromProps
是静态的?
当它设置为静态函数,表明这个函数不能通过 this
访问到 class
的属性,也并不推荐直接访问属性。
- 哪些生命周期可以
setState
?
可以在 componentDidMount
和 componentDidUpdate
中使用,此时 DOM 已经稳定下来了,可以进行数据的操作了。
8.2.2 更新阶段
getDerivedStateFromProps
:此方法在更新阶段也会被调用。shouldComponentUpdate
:shouldComponentUpdate(nextProps, nextState)
,有两个参数,表示新的属性和变化之后的state
,返回一个布尔值。如果是true
表示会触发重新渲染,false
表示不会触发重新渲染,默认返回true
。可以利用这个生命周期来优化 React 程序性能。render
:同挂载阶段render
。getSnapshotBeforeUpdate
:getSnapshotBeforeUpdate(prevProps, prevState)
,这个方法会在render
之后,componentDidUpdate
之前调用,有两个参数,表示之前属性和之前的state
。这个函数有一个返回值,会作为第三个参数传给componentDidUpdate
,如果不需要返回值,可以返回null
,这个方法必须和componentDidUpdate
配合使用。componentDidUpdate
:componentDidUpdate(prevProps, prevState, snapshot)
,在getSnapshotBeforeUpdate
之后调用,有三个参数,表示之前的props
,之前的state
,以及snapshot
。参数snapshot
是getSnapshotBeforeUpdate
返回的,如果触发某些回调函数时需要用到DOM
元素的状态,则将对比或者计算过程迁移到getSnapshotBeforeUpdate
,然后在componentDidUpdate
中统一触发回调或者更新状态。
8.2.3 卸载阶段
componentWillUnmount
:当组件被卸载或者销毁时会被调用,在这里清除定时器,或者取消网络请求,用来清理无效的 DOM 元素等垃圾回收工作。
九 setState
setState
是 React 中用于修改状态,更新视图的方法。
9.1 调用 setState 之后发生了什么?
在代码中调用 setState
之后,React 会将传入的参数对象与组件当前的状态合并,触发所谓的调和过程(Reconciliation
)。
经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。
在 React 得到元素树之后,React 会自动计算新树和老树之间的节点差异,然后根据差异对界面进行最小化重新渲染。
在差异计算算法(Diff
)中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,保证了按需更新,而不是全部重新渲染。
简单来说:
- 合并参数对象,触发调和过程
- 计算新树和老树差异(
Diff
) - 根据差异进行最小化重新渲染
9.2 setState 是同步还是异步?
回答:有时候同步,有时候异步。
setState
在合成事件和钩子函数中是异步的,在原生事件和setTimeout
是同步的。setState
的异步,并不是说内部由异步代码实现,它本身执行的过程和代码是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,从而形成了所谓的异步。setState
可以通过第二个参数setState(partialState, callback)
,在回调方法中拿到更新后的结果。
十 React this 问题
在 React 中有几种方法可以修正 this
的指向,这里例举 4 种方法:
import React, { Component } from 'react'
class App extends Component {
constructor (props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick () {
console.log('jsliang 2020');
}
handleClick2 = () => {
console.log('jsliang 2021');
}
render () {
// 四种绑定方法
return (
<div className='App'>
{/* 方法一:通过 constructor 中进行 bind 绑定 */}
<button onClick={this.handleClick}>btn 1</button>
{/* 方法二:在里边绑定 this */}
<button onClick={this.handleClick.bind(this)}>btn 2</button>
{/* 方法三:通过箭头函数返回事件 */}
<button onClick={() => this.handleClick()}>btn 3</button>
{/* 方法四:让方法变成箭头函数 */}
<button onClick={this.handleClick2}>btn 4</button>
{/* 额外:直接调用不需要绑定 this */}
{this.handleClick()}
</div>
)
}
}
export default App;
那么,使用 bind
和箭头函数有什么区别吗?
箭头函数除了代码少,与普通函数最大的不同就是:this
是由声明该函数时候定义的,一般是隐性定义为声明该函数时的作用域 this
。
通过 bind
的话,相当于:Foo.prototype.a = function() {}
,是通过原型链的一个指正绑定。
而通过箭头函数的话,就相当于:
class Foo {
constructor() {
this.a = () => {};
}
}
十一 受控组件和非受控组件
在 Ant Design
中,对 Input
输入框进行操作,如果是改变 defaultValue
会发现毫无作用。
这是因为 React 的 form
表单组件中的 defaultValue
一经传递值后,后续改变 defaultValue
都将不起作用,被忽略了。
具体来说这是一种 React 非受控组件,其状态是在 input
的 React 内部控制,不受调用者控制。
所以受控组件就是可以被 React 状态控制的组件。双向数据绑定就是受控组件,你可以为 form
中某个输入框添加 value
属性,然后控制它的一个改变。而非受控组件就是没有添加 value
属性的组件,你并不能对它的固定值进行操作。
十二 组件通讯
- 父组件向子组件通讯:父组件向子组件传
props
方式,向子组件进行通讯。 - 子组件向父组件通讯:父组件在
props
中传递方法,然后子组件调用这个方法,将自身需要传递的信息,传递到父组件的作用域中。 - 复杂点的通讯:借助 React 的
Context
,或者Redux
进行数据通讯。
十三 Redux
网上有挺多关于 Redux
、React-Redux
、Redux-Saga
的使用,这里就不废话介绍了,还是讲讲 jsliang 在工作中的一个使用吧。
工作目录
- 某个页面文件夹
- View.jsx 当前页面主入口
- Child.jsx 子组件
- Brother.jsx 兄弟组件
- action.js 动作
- types.js 类型
- saga.js 调用接口
- reducers.js 处理数据
正常的一个工作目录如上所示,我们工作中是怎么个使用方式呢?
首先,在 View.jsx
中通过 React-Redux
连接 React
和 Redux
然后,假设现在 Child.jsx
需要调用接口(异步处理),那么会:
- 在
action.js
中定义这个方法,会传递什么参数。 - 其中
types.js
是辅助action.js
的一个内容,为了防止方法体的重复,我们会在types.js
中定义大写的action
名字。 - 这时候就可以在
View.jsx
中通过dispatch
触发方法,例如dispatch(getPage(page, perPage))
。 - 这时候,在
reducers.js
中和sage.js
中都能监听到这个方法,但是我们是在sage.js
中调用接口并处理数据。 - 处理完毕之后,再将
sage.js
中的传递给reducers.js
中,让它去处理数据。
接着,如果 Brother.jsx
只是单纯地想处理数据并在 Child.jsx
中使用,那么我们处理方式是跟上面一样的,只是直接在 reducers.js
中处理,而不需要再在 sage.js
中调用接口而已。
最后,我们再看看 redux
和 react-reduxt
的工作流程加深印象:
Redux
React-Redux
十四 Mixin、HOC 和 Hook
前端发展速度非常之快,页面和组件变得越来越复杂,如何更好的实现 状态逻辑复用 一直都是应用程序中重要的一部分,这直接关系着应用程序的质量以及维护的难易程度。
Mixin
、HOC
和 Hook
是 React 采用的 3 种 状态逻辑复用 的技术,Mixin
已被抛弃,HOC
正当壮年,Hook
初露锋芒,掌握它迭代因素和规律非常重要。
14.1 Mixin
Mixin
(混入)是一种通过扩展收集功能的方式,它本质上是将一个对象的属性拷贝到另一个对象上面去。
不过你可以拷贝任意多个对象的任意个方法到一个新对象上去,这是继承所不能实现的。
它的出现主要就是为了解决代码复用问题。
但是,它会带来一些危害:
Mixin
相互依赖、相互耦合,不利于代码维护- 不同的
Mixin
中的方法可能会互相冲突 Mixin
非常多时,组件是可以感知到的,甚至还要为其做相关处理,这样给代码造成滚雪球式的复杂性。
14.2 高阶组件(HOC)
基于 Mixin
的问题,React 推出对装饰模式的一种实现:高阶组件(HOC
)。
高阶组件接收一个组件作为参数,并返回一个新的组件。
高阶组件(
HOC
)是 React 中的高级技术,用来重用组件逻辑。但高阶组件本身并不是 React API。它只是一种模式,这种模式是由 React 自身的组合性质必然产生的。
function visible(WrappedComponent) {
return class extends Component {
render() {
const { visible, ...props } = this.props;
if (visible === false) return null;
return <WrappedComponent {...props} />;
}
}
}
高阶组件可以应用于 日志打点、可用权限控制、双向绑定、表单校验等。
高阶组件解决了 Mixin
带来的问题:
- 低耦合。高阶组件就是一个没有副作用的纯函数,各个高阶组件不会互相依赖耦合
- 避免冲突。高阶组件也有可能造成冲突,但我们可以在遵守约定的情况下避免这些行为
- 副作用小。高阶组件并不关心数据使用的方式和原因,而被包裹的组件也不关心数据来自何处。高阶组件的增加不会为原组件增加负担
但是,有光的地方总有暗,高阶组件也存在一些缺陷:
HOC
需要在原组件上进行包裹或者嵌套,如果大量使用HOC
,将会产生非常多的嵌套,这让调试变得非常困难。HOC
可以劫持props
,在不遵守约定的情况下也可能造成冲突。
14.3 Hook
Hook
是 React v16.7.0-alpha
中加入的新特性。它可以让你在 class
以外使用 state
和其他 React 特性。
使用 Hook
,你可以在将含有 state
的逻辑从组件中抽象出来,这将可以让这些逻辑容易被测试。
同时,Hook
可以帮助你在不重写组件结构的情况下复用这些逻辑。
所以,它也可以作为一种实现状态逻辑复用的方案。
Hook
使用带来的好处:
- 减少状态逻辑复用的风险:
Hook
和Mixin
在用法上有一定的相似之处,但是Mixin
引入的逻辑和状态是可以相互覆盖的,而多个Hook
之间互不影响,这让我们不需要在把一部分精力放在防止避免逻辑复用的冲突上。 - 避免地狱式嵌套:大量使用
HOC
的情况下让我们的代码变得嵌套层级非常深,使用Hook
,我们可以实现扁平式的状态逻辑复用,而避免了大量的组件嵌套。 - 让组件更容易理解:在使用
class
组件构建我们的程序时,他们各自拥有自己的状态,业务逻辑的复杂使这些组件变得越来越庞大,各个生命周期中会调用越来越多的逻辑,越来越难以维护。使用Hook
,可以让你更大限度的将公用逻辑抽离,将一个组件分割成更小的函数,而不是强制基于生命周期方法进行分割。 - 使用函数代替 class:相比函数,编写一个
class
可能需要掌握更多的知识,需要注意的点也越多,比如this
指向、绑定事件等等。另外,计算机理解一个函数比理解一个class
更快。Hooks
让你可以在class
之外使用更多 React 的新特性。
十五 性能优化
- 首屏渲染优化。
<div id="root"> SVG </div>
,也可以使用插件prerender-spa-plugin
插件进行首屏渲染。 - 页面切换优化。使用
html-webpack-plugin
插件自动插入loading
,这样切换的时候,就不需要在每个页面都写一套loading
。 - 减少业务代码体积。通过
Tree Shaking
来减少一些代码。 - 提取公共代码。通过
SplitChunkPlugin
自动拆分业务基础库,减少大文件的存在。 - 切分代码。通过
Code Splitting
来懒加载代码,提高用户的加载体验。例如通过React Loadable
来将组件改写成支持动态import
的形式。 - 懒加载。React 可以通过
react-lazyload
这种成熟组件来进行懒加载的支持。 - 页面占位。有时候加载页面的文本、图片的时候,会出现 “闪屏” 的情况,比如图片或者文字没有加载完毕,对应位置空白,然后加载完毕,会突然撑开页面,导致闪屏。这时候使用第三方组件
react-placeholder
可以解决这种情况。
十六 参看文献
本系列有 67 篇参考文献。
16.1 面试知识点
2019:
- 2019年17道高频React面试题及详解【阅读建议:1h】
2018:
- 关于React面试题汇总【阅读建议:5min】
- 常见react面试题汇总(适合中级前端)【阅读建议:20min】
2017:
- React 常用面试题目与分析【阅读建议:5min】
16.2 系统
- React技术揭秘【阅读建议:无】
- (中篇)中高级前端大厂面试秘籍,寒冬中为您保驾护航,直通大厂【阅读建议:30min】
2017:
- 从零搭建React全家桶框架教程【阅读建议:无】
16.3 React 和 Vue 比对
2020:
- Vue和React的区别,你在用哪个呢?【阅读建议:10min】
- 你不知道的React 和 Vue 的20个区别【面试必备】
2017:
- Vue与React两个框架的区别和优势对比【阅读建议:10min】
16.4 生命周期
最新:
- React 生命周期查看【阅读建议:10min】
2019:
- React 的生命周期变化【阅读建议:5min】
- React生命周期【阅读建议:5min】
2018:
- React v16.3 版本新生命周期函数浅析及升级方案【阅读建议:20min】
2017:
- 深入React的生命周期(上):出生阶段(Mount)【阅读建议:无】
- 深入React的生命周期(下):更新(Update)【阅读建议:无】
16.5 受控组件和非受控组件
2019:
2016:
16.6 Diff 和 虚拟 DOM
2019:
- 让虚拟DOM和DOM-diff不再成为你的绊脚石【阅读建议:20min】
2018:
- 深入框架本源系列 —— Virtual Dom【阅读建议:30min】
- 浅入浅出图解 Dom Diff【阅读建议:30min】
- 探索Virtual DOM的前世今生【阅读建议:30min】
- 你不知道的Virtual DOM系列【阅读建议:20min】
2017:
- React 源码剖析系列 - 不可思议的 react diff【阅读建议:30min】
- 你真的了解React吗(上)如何设计组件以及重要的生命周期【阅读建议:无】
2015:
- 深度剖析:如何实现一个 Virtual DOM 算法【阅读建议:无】
16.7 React 源码
2018:
- 怎样学习React?当然是自己动手实现一个React啦【阅读建议:无】
- 《React源码解析》系列完结!【阅读建议:无】
- 精读《用160行js代码实现一个React》【阅读建议:无】
2017:
- React 源码解析【阅读建议:无】
- React源码解析(三):详解事务与更新队列【阅读建议:无】
- React-Redux源码分析【阅读建议:无】
- 源码看React setState漫谈(一)【阅读建议:无】
- 源码看React setState漫谈(二)【阅读建议:无】
- Mobx 思想的实现原理,及与 Redux 对比【阅读建议:无】
2015:
- React 源码剖析系列 - 生命周期的管理艺术【阅读建议:无】
- React 源码剖析系列 - 玩转 React Transition【阅读建议:无】
16.8 React Mixin
2015:
- React Mixin 的前世今生【阅读建议:无】
16.9 React Hoc
2019:
- React 中的高阶组件及其应用场景【阅读建议:40min】
2017:
- React 高阶组件(HOC)入门指南【阅读建议:10min】
- 深入理解 React 高阶组件【阅读建议:10min】
16.10 React Hooks
2019:
- 【React深入】从Mixin到HOC再到Hook【阅读建议:30min】
- useEffect 完整指南【阅读建议:无】
- React Hooks 原理【阅读建议:30min】
- React Hooks 详解 【近 1W 字】+ 项目实战【阅读建议:3h】
2018:
- 30分钟精通React今年最劲爆的新特性——React Hooks【阅读建议:30min】
16.11 React Fiber
2018:
- 完全理解React Fiber【阅读建议:20min】
- React Fiber架构【阅读建议:20min】
- React Fiber 架构介绍资料汇总【阅读建议:20min】
16.12 服务端渲染(SSR)
- 从头开始,彻底理解服务端渲染原理(8千字汇总长文)【阅读建议:2h】
16.13 性能优化
2019:
- React 最佳实践【阅读建议:20min】
2018:
- React 16 加载性能优化指南【阅读建议:20min】
- React中型项目的优化实践【阅读建议:10min】
2017:
- 如何提高你的 React 应用的性能【阅读建议:10min】
- 将 React 应用优化到 60fps【阅读建议:5min】
16.14 其他
2019:
- styled-components:前端组件拆分新思路【阅读建议:5min】
2018:
- 组件库设计实战 - 复杂组件设计【阅读建议:无】
- 前端数据校验从建模开始【阅读建议:20min】
- React 应用设计之道 - curry 化妙用【阅读建议:20min】
- 如何评价React的新功能Time Slice 和Suspense?【阅读建议:20min】
- 如何写出更好的 React 代码?【阅读建议:20min】
- React ref 的前世今生【阅读建议:20min】
- 你真的理解setState吗?【阅读建议:10min】
- 【译】通过Recompose库掌握React函数组件【阅读建议:10min】
- 还在用 Redux,要不要试试 GraphQL 和 Apollo【阅读建议:5min】
2017:
- 你真的了解React吗(中)组件间的通信以及React优化【阅读建议:10min】
2015:
- React 源码剖析系列 - 解密 setState【阅读建议:无】
jsliang 的文档库由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议 进行许可。
基于 github.com/LiangJunron… 上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。