4

生命周期

 1 year ago
source link: http://muyunyun.cn/blog/dr9fpnig/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

3.生命周期

先来回顾 React 的生命周期, 用流程图表示如下:

77e8b5ceaa1d697f280053be91a87bb3.jpg

该流程图比较清晰地呈现了 react 的生命周期。其分为 3 个阶段 —— 生成期, 存在期, 销毁期。

因为生命周期钩子函数存在于自定义组件中, 将之前 _render 函数作些调整如下:





// 原来的 _render 函数, 为了将职责拆分得更细, 将 virtual dom 转为 real dom 的函数单独抽离出来
function vdomToDom(vdom) {
if (_.isFunction(vdom.nodeName)) { // 为了更加方便地书写生命周期逻辑, 将解析自定义组件逻辑和一般 html 标签的逻辑分离开
const component = createComponent(vdom) // 构造组件
setProps(component) // 更改组件 props
renderComponent(component) // 渲染组件, 将 dom 节点赋值到 component
return component.base // 返回真实 dom

我们可以在 setProps 函数内(渲染前)加入 componentWillMount, componentWillReceiveProps 方法, setProps 函数如下:





function setProps(component) {
if (component && component.componentWillMount) {
component.componentWillMount()
} else if (component.base && component.componentWillReceiveProps) {
component.componentWillReceiveProps(component.props) // 后面待实现

而后我们在 renderComponent 函数内加入 componentDidMountshouldComponentUpdatecomponentWillUpdatecomponentDidUpdate 方法





function renderComponent(component) {
if (component.base && component.shouldComponentUpdate) {
const bool = component.shouldComponentUpdate(component.props, component.state)
if (!bool && bool !== undefined) {
return false // shouldComponentUpdate() 返回 false, 则生命周期终止
if (component.base && component.componentWillUpdate) {
component.componentWillUpdate()
const rendered = component.render()
const base = vdomToDom(rendered)
if (component.base && component.componentDidUpdate) {
component.componentDidUpdate()
} else if (component && component.componentDidMount) {
component.componentDidMount()
if (component.base && component.base.parentNode) { // setState 进入此逻辑
component.base.parentNode.replaceChild(base, component.base)
component.base = base // 标志符

测试生命周期

测试如下用例:





class A extends Component {
componentWillReceiveProps(props) {
console.log('componentWillReceiveProps')
render() {
return (
<div>{this.props.count}</div>
class B extends Component {
constructor(props) {
super(props)
this.state = {
count: 1
componentWillMount() {
console.log('componentWillMount')
componentDidMount() {
console.log('componentDidMount')
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate', nextProps, nextState)
return true
componentWillUpdate() {
console.log('componentWillUpdate')
componentDidUpdate() {
console.log('componentDidUpdate')
click() {
this.setState({
count: ++this.state.count
render() {
console.log('render')
return (
<div>
<button onClick={this.click.bind(this)}>Click Me!</button>
<A count={this.state.count} />
</div>
ReactDOM.render(
<B />,
document.getElementById('root')

页面加载时输出结果如下:





componentWillMount
render
componentDidMount

点击按钮时输出结果如下:





shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate

React 16.3 生命周期调研

在这个版本中, 新加入了两个生命周期:





getDerivedStateFromProps(nextProps, prevState): 更加语义化, 可以代替 componentWillMount、componentWillReceiveProps(nextProps);
getSnapshotBeforeUpdate(prevProps, prevState): 可以将结果传入 componentDidUpdate 里, 从而达到 dom 数据统一, 可以替代 componentWillUpdate()(缺点就是前面讲的 react 开启异步渲染, componentWillUpdate() 与 componentDidUpdate() 间获取的 dom 会不统一)。

后文考虑实现上述 api。

React 16.3 生命周期相关文献


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK