基础概念
- Virtual DOM(Diff算法)
- Jsx 语法
- Flux Data Flow(单向数据流)
- 类组件&生命周期
- 函数组件-无状态组件FSC
- 高阶特性
Hoc
Render Props
Context
等
生命周期
在挂载过程中有四个生命周期方法,它们的调用顺序是这样的:
constructor()
组件初始化时被调用,用于初始化状态componentWillMount()
在render()
之前被调用。可用于设置一些组件本地状态,不过还是推荐在constructor()
中去初始化状态。render()
它返回作为组件输出的元素。这个方法应该是一个纯函数,因此不应该在这个方法中修改组件的状态。componentDidMount()
它仅在组件挂载后执行一次。一般用于处理Ajax
请求等副作用。
共有5个生命周期方法用于组件更新周期,调用顺序如下:
componentWillReceiveProps(nextProps)
新的属性会作为它的输入。因此你可以利用this.props
来对比之后的属性和之前的属性,基于对比的结果去实现不同的行为。此外,你可以基于新的属性来设置组件的状态。shouldComponentUpdate((nextProps, nextState)
每次组件因为状态或者属性更改而更新时,它都会被调用。组件及其子组件将根据该方法返回的布尔值来决定是否重新渲染,从而避免不必要的渲染。用于性能优化。componentWillUpdate((nextProps, nextState)
- 这个方法是render()
执行之前的最后一个方法。你已经拥有下一个属性和状态,它们可以在这个方法中任由你处置。你可以利用这个方法在渲染之前进行最后的准备。注意在这个生命周期方法中你不能再触发setState()
。如果你想基于新的属性计算状态,你必须利用componentWillReceiveProps()
。render()
同上。componentDidUpdate()
这个方法在render()
之后立即调用。你可以用它当成操作DOM
或者执行更多异步请求的机会。
组件卸载也有生命周期。只有一个:
componentWillUnmount()
。它会在组件销毁之前被调用。你可以利用这个生命周期方法去执行任何清理任务。
componentDidCatch()
。它在React 16
中引入,用来捕获组件的错误。
setState() 异步?
setState
只在合成事件和钩子函数中是“异步”的,在原生事件和setTimeout
中都是同步的。setState
的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数setState(partialState, callback)
中的callback
拿到更新后的结果。setState
的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout
中不会批量更新,在“异步”中如果对同一个值进行多次setState
,setState
的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时setState
多个不同的值,在更新时会对其进行合并批量更新。
React Hooks
Hook
是 React 16.8
的新增特性。它可以让你在不编写 class
的情况下使用 state
以及其他的 React
特性。
- 基础 Hook :
useState
useEffect
useContext
- 其他 Hook :
useReducer
useCallback
useMemo
useRef
useImperativeHandle
useLayoutEffect
useDebugValue
React SSR
- CSR 客户端渲染
- SSR 服务端渲染
- SPA 单页应用
SSR
其实属于古老的技术了,早期的前端页面都是SSR
渲染的,node + ejs(模版引擎),java + (velocity模版引擎),php,jsp
等都可以实现。但是只实现SSR
其实没啥意义,技术上没有任何发展和进步,否则 SPA
技术就不会出现。
但是单纯的 SPA
又不够完美,所以最好的方案就是这两种体验和技术的结合,第一次访问页面是服务端渲染,基于第一次访问后续的交互就是 SPA
的效果和体验,还不影响SEO
效果,这就有点完美了。关于React SSR
,主要有下面几个框架:
Nextjs
React
轻量级后端渲染框架,同构渲染利器。
Umijs
Umi
,中文可发音为乌米,是可扩展的企业级前端应用框架,参考 next.js
做的。要说有哪些地方不如Umi
,我觉得可能是不够贴近业务,不够接地气。比如 antd、dva
的深度整合,比如国际化、权限、数据流、配置式路由、补丁方案、自动化 external 方面等等一线开发者才会遇到的问题。
Bigfish(阿里内部,非开源)
Umi
和Bigfish
,前者是从无线业务中长出来的,后者是从中台业务中长出来的。- 后来统一技术栈,
Bigfish
后来改造成umi + umi 插件集
的一个架构。这样一个对外开源,一个对内服务。类似的还有eggjs
和chair
。
既然是阿里内部框架,这里为啥提及:这是一种很好的方式,开源和业务两不误
Eggjs
企业级Node.js
框架, 基于 Koa
开发,性能优异,高度可扩展的插件机制,内置多进程管理。
有成熟的配合React实现SSR技术解决方案
Redux
Redux
是 JavaScript 状态容器,提供可预测化的状态管理。
redux-saga
异步解决方案,相似仓库还有:
redux-thunk
redux-promise
dav
基于 redux
和 redux-saga
的数据流方案,额外内置了 react-router
和 fetch
,所以也可以理解为一个轻量级的应用框架。
好文
React SSR详解
Egg + React + SSR 服务端渲染
蚂蚁金服前端框架和工程化实践
React + Redux 最佳实践
支付宝前端应用架构的发展和选择
你真的理解setState吗?