Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

详细梳理react的生命周期 #14

Open
zp1112 opened this issue May 14, 2018 · 0 comments
Open

详细梳理react的生命周期 #14

zp1112 opened this issue May 14, 2018 · 0 comments
Labels

Comments

@zp1112
Copy link
Owner

zp1112 commented May 14, 2018

constructor

组件初始化函数,用于初始化状态,包括继承props和初始化state,所以没有必要在constructor里面执行setState,不会触发重新渲染,除非是异步的。

constructor(props) {
  super(props);
  this.state = {
    val: 0
  }
}
render() {
  console.log(33333);
  return ({this.state.val})
}

componentWillMount

组件即将渲染,在整个生命周期里面只会加载一次,在componentWillMount里面执行setState,不会触发重新渲染,除非是异步的。

componentWillMount() {
    setTimeout(() => this.setState({
      val: 999
    }), 2000)
  }
// 先打印33333
// 2s后打印33333
componentWillMount() {
    this.setState({
      val: 999
    }
  }
// 打印一次33333

render

组件执行渲染,将虚拟dom渲染到真实dom。在这里不能执行setState,否则会触发循环。除非使用PureComponent,但是也会出现warning,而且在多层嵌套的对象改变的时候依然会死循环,因为PureComponent只是浅比较

componentDidMount

render渲染完毕后到这一步,通常在这里面可以用于获取服务器一些数据,改变state状态,会触发重新render,当然到底触不触发还取决于改变的值和shouldComponentUpdate。

componentWillReceiveProps(prevProp)

当prop改变的时候触发,在这里面不能改变props,否则会陷入死循环!!,除非增加判断条件,避免陷入死循环。在这里面执行setState,会触发shouldComponentUpdate

shouldComponentUpdate(newProps, newState)

当prop或state改变时触发,返回值是true的话会触发重新render,false不触发。在这里面不能执行setState,否则会陷入死循环!!

componentWillUpdate(newProps, newState)

当props和state改变时,触发shouldComponentUpdate,如果返回false,则不会走到componentWillUpdate,如果返回true,则会触发componentWillUpdate

componentWillUnmount

组件卸载的时候调用这个函数,可以在这里做一些定时器的销毁等操作。

补充setState异步更新

由于setState是异步更新的,所以当你执行setState的时候在当前事件循环中不能立即使用改变后的state

this.state = { test: 'hello' }
...
this.setState({
      test: 'world'
    })
console.log(this.state.test) // hello

如何使之可以立即使用呢

this.setState({
  test: 'world'
}, () => console.log(this.state.test)) // world

由于setState的批量更新机制,react利用事务来实现队列,在一个调用栈中的setState都会推到队列里面(哇,不懂),会发生如下情况

handleClick() {
  this.setState({
     val: this.state.val + 1
  });
   //第一次输出
   console.log(this.state.val);
   this.setState({
      val: this.state.val + 1
   });
   //第二次输出
   console.log(this.state.val);
   setTimeout(()=>{
      this.setState({val: this.state.val + 1});
       //第三次输出
       console.log(this.state.val);
       this.setState({
          val: this.state.val + 1
       });
       //第四次输出
       console.log(this.state.val);
   }, 0);
}
render() {
  console.log(2333333); // 打印出来查看render次数
  return ({this.state.val})
}

控制台打印出

0
0
2333333 // 两次setState批量更新后的render 得到state.val == 1
2333333 // 第三次setState立即更新
2
2333333 // 第四次setState立即更新
3

为何会这样呢,请看setState详解

@zp1112 zp1112 added the react label May 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant