React 生命周期详解

2018-01-23  本文已影响0人  前端河豚

React 生命周期详解

生命周期的三个阶段

装载过程

该过程会调用以下函数

  1. constructor () 该函数是可为了初始化state和绑定this
  2. getInitialState () 此函数是ES5写法中初始化state,,在ES6中已经弃用,
  3. getDefaultProps() 此函数是ES5写法中初始化props,在ES6中已经弃用,
  4. componentWillMount () 该函数是组件挂载之前调用,只执行一次,可在此函数中使用setState, 该设置的state可以在第一次渲染中看到,
  5. render () 渲染组件,组件中必须要有该函数,
  6. componentDidMount () 该函数是组件挂载完成之后调用, 只执行一次,此时已生成真实DOM节点,这里可以使用refs。可在此函数中调用ajax或者设置state, 该设置的 state可以在第一次渲染中看到。

更新过程

当组件或父组件的propsstate改变时就会触发更新过程
该过程会调用以下函数

  1. componentWillReceiveProps (nextProps) 该函数是父组件render时 会调用此函数,nextProps是父组件传递给子组件的数据, 不管父子组件有没有数据交换,或者props有没有更新,此函数都会执行。
  2. shouldComponentUpdate (nextProps, nextState) 组件挂载之后在组件更新之前,判断nextPropsnextStatepropsstate的数据是否改变,是否需要重新渲染。默认不写此函数时返回true,重新渲染,返回false不重新渲染。在大型应用中有些数据的更新并不影响页面的展示,则可以在此函数中做判断,优化渲染效率。
  3. componentWillUpdate (nextProps, nextState) 组件更新之前,当shouldComponentUpdate函数返回true 时会调用此函数。在此函数中不能使用setState,否则会陷入死循环。
  4. render () 重新渲染DOM
  5. componentDidUpdate (prevProps, prevState) 组件更新之后,除了初次渲染外,每次的render都会调用该函数,渲染结束执行的函数可在此函数中调用。在此函数中不能使用setState,否则会陷入死循环。

卸载过程

当组件从DOM树种移除时会触发卸载过程
在该函数中可以清除在componentDidMount中设置的监听函数removeEventListener ,或者在此函数中清除一些setTimeOutsetInterval

React 示例

子组件

import React from 'react'

class TodoList extends React.Component {
  constructor(props, context) {
    super(props)
    this.state = {
      // 初始化state
      mount: false
    }
  }

  componentWillMount() {
    // 组件挂载之前
    console.log('组件挂载之前')
  }

  componentDidMount() {
    // 组件挂载之后
    console.log('组件挂载之后')
    this.setState({
      mount: true
    })
  }

  componentWillReceiveProps(nextProps) {
    // 父组件重新渲染时调用
    console.log('父组件重新渲染时调用')
  }

  shouldComponentUpdate(nextProps, nextState) {
    // 组件挂载之后数据更新之后
    console.log('组件挂载之前,数据更新之后');
    // 默认情况下是返回true
    return true;
  }

  componentWillUpdate(nextProps, nextState) {
    // 数据重新渲染之前
    console.log('数据重新渲染之前');
  }
  
  componentDidUpdate(prevProps, prevState) {
    // 数据重新渲染之后
    console.log('数据重新渲染之后');
  }
  
  componentWillUnmount() {
    // 组件卸载
    console.log('组件卸载'); 
  }
  
  render() {
    // 渲染函数  每个组件必须要有
    console.log('render');
    return (
      <div>
        render
      </div>
    )
  }
};

export default TodoList;

父组件

import React from 'react'
import TodoList from './components/todoList/index'
export default class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = { 
       initDone: false
    }
  }

  componentDidMount() {
    this.setState({
      initDone: true
    })
  }
  
  render () {
    return (
      <div>
        <TodoList />
      </div>
    )
  }
}
export default App;

渲染到HTML

import { render } from "react-dom"
import App from './App'

render(
  <App/>,
  document.getElementById('root')
)

控制台输出结果

组件挂载之前
render
组件挂载之后
父组件重新渲染时调用
组件挂载之前,数据更新之后
数据重新渲染之前
render
数据重新渲染之后

后续会做一个官方的经典例子TODOLIST

学习是一个不断进步的过程,希望每一位程序猿都向自己的梦想迈进一步!

上一篇 下一篇

猜你喜欢

热点阅读