各阶段钩子的执行顺序image.png

constructor:初始化

  • 如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。
  • 在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前前调用 super(props)。否则,this.props 在构造函数中可能会出现未定义的 bug。

    1. class App extends React.Component {
    2. constructor(props){ // 创建时,挂载之前
    3. super(props)
    4. }
    5. }

    shouldComponentUpdate:是否更新 UI

  • state 地址改变,但是数据内容不变时不进行更新

    1. class App extends React.Component {
    2. constructor(props) {
    3. super(props);
    4. this.state = {n: 0};
    5. }
    6. add = () => { // 先加1再减1,结果不变,改变地址
    7. this.setState( (state)=> ({n: state.n + 1}) )
    8. this.setState( (state)=> ({n: state.n - 1}) )
    9. }
    10. shouldComponentUpdate(nextProps, nextState){
    11. return !( this.state.n === nextState.n ) // 对比新旧 state.n
    12. // 等同于 this.state.n === nextState.n ? false : true
    13. }
    14. render() {
    15. return (<h1> n:{this.state.n}
    16. <button onClick={ this.add }>+1</button> // button.onClick.call(null,event)
    17. </h1>)
    18. }
    19. }
  • class App extends React.PureConponent 对比新旧 state、props 的所有 key 的值

    1. class Hello extends React.PureComponent {
    2. constructor(props) {
    3. super(props);
    4. this.state = {n: 0};
    5. }
    6. add = () => { // 先加1再减1,结果不变,改变地址
    7. this.setState( (state)=> ({n: state.n + 1}) )
    8. this.setState( (state)=> ({n: state.n - 1}) )
    9. }
    10. render() {
    11. return (<h1> n:{this.state.n}
    12. <button onClick={ this.add }>+1</button> // button.onClick.call(null,event)
    13. </h1>)
    14. }
    15. }

    render:创建虚拟 DOM

  • class 组件中唯一必须实现的方法

  • 只能有一个根元素,如果有多个需要用 <React.Fragment></React.Fragment> 包裹,简写 <></>

    1. class Hello extends React.Component {
    2. render() {
    3. return (
    4. <>
    5. <div>xxx</div>
    6. <div>yyy</div>
    7. </>
    8. )
    9. }
    10. }

    componentDidMount:挂载到页面

  • 首次渲染执行

  • 挂载之后才可以获取 dom
  • 官方推荐此时发起加载数据的 AJAX 请求

    1. class App extends React.Component {
    2. constructor(props) {
    3. super(props)
    4. const div = document.getElementById('xxx')
    5. console.log(div) // null
    6. }
    7. componentDidMount() {
    8. const div = document.getElementById('xxx')
    9. console.log(div) // <div id="xxx">你好</div>
    10. }
    11. render() {
    12. return (<div id='xxx'>你好</div>)
    13. }
    14. }

    ref

    1. class App extends React.Component {
    2. constructor(props) {
    3. super(props)
    4. this.divRef = React.createRef()
    5. }
    6. componentDidMount() {
    7. const div = this.divRef.current
    8. console.log(div) // <div id="xxx">你好</div>
    9. }
    10. render() {
    11. return (<div ref={ this.divRef }>你好</div>)
    12. }
    13. }

    componentDidUpdate(prevProps,prevState):组件更新

  • 首次渲染不会执行

  • 此时 setState 会无限循环,除非放在 if 语句里
  • 如果 shouldComponentUpdate 返回 false,则不会触发此钩子

    componentWillUnmount():组件即将消亡

  • 元素即将消亡时执行

  • 此时应对长期有效的监听、计时器或 AJAX 进行取消

    componentWillReceiveProps:poops变化时 - 弃用

    UNSAFE_componentWillReceiveProps