React生命周期

109 阅读3分钟

1.旧版本

img

# 1.挂载
# 2.更新 setState forupdate

class App extends React.Component {
  // 构造函数
  constructor(props) {
    super(props)
    console.log('constructor') // => 1, 1次
    this.state = {
      count: 0
    }
  }
  // 组件将要挂载
  componentWillMount() { // 这个生命周期已经rename
    console.log('componentWillMount') // => 2, 1次
  }
  // 组件已经挂载
  componentDidMount() {
    console.log('componentDidMount') // => 4, 1次
  }
  
  // 控制组件更新
  // 不单独声明,则默认返回true,返回值必须为布尔值, 返回true则更新,继续其他生命周期,返回false则停止
  shouldComponentUpdate() {
    console.log('shouldComponentUpdate')
    return true
  }
  
  // 组件将要更新
  componentWillUpdate() { // 这个生命周期已经rename
    console.log('componentWillUpdate')
  }
  
  // 组件已经更新
  componentDidUpdate() {
    console.log('componentDidUpdate')
  }
  
  // 组件将被移除
  componentWillUnmount() {
    console.log('componentWillUnmount') // => 5. 1次
  }
  // 组件渲染
  render() {
    console.log('render') // => 3, 1+n次
    return (
      <div>
        React生命周期--{this.state.count}
        <button onClick={() => this.change()}>click</button>
        <button onClick={() => this.remove()}>remove</button>
      <button onClick={() => this.force()}>force</button>
      </div>
    )
  }
  // 更新状态
  change() {
    let count = this.state.count
    this.setState({ count: count + 1}) // React不支持自增(++)自减(--)
  }
  // 卸载组件
  remove() {
    ReactDOM.unmountComponentAtNode(document.getElementById('root')) // ReactDOM 主动卸载组件
  }
  // 强制更新
  force() {
    this.forceUpdate()
  }
}
# 父组件更新触发子组件

class Child extends React.Component {
  // 组件将要接收新的props
  componentWillReceiveProps() { // 这个生命周期已经rename
    console.log('Child, componentWillReceiveProps')
  }
  
  // 控制组件更新
   shouldComponentUpdate() {
    console.log('shouldComponentUpdate')
    return true
  }
 
  // 组件将要更新
  componentWillUpdate() { // 这个生命周期已经rename
    console.log('componentWillUpdate')
  }
  
  // 组件已经更新
  componentDidUpdate() {
    console.log('componentDidUpdate')
  }
  
  render() {
    console.log('render')
    return (
      <div>child {this.props.count}</div>
    )
  }
}
class App extends React.Component {
  state = {
    count: 0
  }
  change() {
    let count = this.state.count
    this.setState({ count: count + 1 })
  }
  render() {
    return (
      <div>
        <Child />
        <div>father</div>
        <div>{this.state.count}</div>
        <button onClick={() => this.change()}>change</button>
      </div>
    )
  }
}

2.更名的声明周期

# 1.挂载
# 2.更新 setState forupdate

class App extends React.Component {
  // 构造器
  constructor(props) {
    console.log('constructor')
    super(props)
    this.state = {
      count: 0
    }
  }
  // 组件将要挂载
  UNSAFE_componentWillMount() {
    console.log('UNSAFE_componentWillMount')
  }
  // 组件已经挂载
  componentDidMount() {
    console.log('componentDidMount')
  }
  // 组件将要卸载
  componentWillUnmount() {
    console.log('componentWillUnmount')
  }
  // 控制组件更新
  shouldComponentUpdate() {
    console.log('shouldComponentUpdate')
    return false
  }
  // 组件将要更新
  UNSAFE_componentWillUpdate() { 
    console.log('UNSAFE_componentWillUpdate')
  }
  // 组件已经更新
  componentDidUpdate() {
    console.log('componentDidUpdate')
  }
  // 组件渲染
  render () {
    console.log('render')
    return (
      <div>
      React声明周期
      <div>{this.state.count}</div>
      <button onClick={() => this.change()}>change</button>
      <button onClick={() => this.remove()}>remove</button>
      <button onClick={() => this.force()}>force</button>
      </div>
    )
  }
  change() {
    const count = this.state.count
    this.setState({ count: count + 1 })
  }
  remove() {
    ReactDOM.unmountComponentAtNode(document.getElementById('root'))
  }
  force() {
    this.forceUpdate()
  }
}
# 父组件更新触发子组件

class Child extends React.Component {
  // 组件将要接收新的props
  UNSAFE_componentWillReceiveProps() {
    console.log('UNSAFE_componentWillReceiveProps')
  }
  render() {
    return (
      <div>
        <div>Child</div>
        <div>{this.props.count}</div>
      </div>
    )
  }
}

class App extends React.Component {
  state = {
    count: 0
  }
  render() {
    return (
      <div>
        <Child count={this.state.count} />
        <div>Father</div>
        <div>{this.state.count}</div>
        <button onClick={() => this.change()}>change</button>
      </div>
    )
  }
  change() {
    const count = this.state.count
    this.setState({ count: count + 1 })
  }
}

2.新版本

# 新加入的生命周期:getDerivedStateFromProps(极少使用)

<App count={200} />
    
class App extends React.Component {
  // 构造器
  constructor(props) {
    console.log('constructor')
    super(props)
    this.state = {
      count: 0
    }
  }
  componentDidMount() {
    console.log('componentDidMount')
  }
  // getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
  // 它应返回一个对象来更新 state,如果返回 null 则不更新任何内容
  // 此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。
  // 例如,实现 <Transition> 组件可能很方便,该组件会比较当前组件与下一组件,以决定针对哪些组件进行转场动画。
  // 派生状态会导致代码冗余,并使组件难以维护
  static getDerivedStateFromProps(props) {
    console.log('getDerivedStateFormProps', props)
    return {
      count: props.count
    }
  }

  // 组件渲染
  render () {
    console.log('render')
    return (
      <div>
      React声明周期
      <div>{this.state.count}</div>
      <button onClick={() => this.change()}>change</button>
      <button onClick={() => this.remove()}>remove</button>
      <button onClick={() => this.force()}>force</button>
      </div>
    )
  }
  change() {
    const count = this.state.count
    this.setState({ count: count + 1 })
  }
  remove() {
    ReactDOM.unmountComponentAtNode(document.getElementById('root'))
  }
  force() {
    this.forceUpdate()
  }
}
# 新加入的生命周期:getSnapshotBeforeUpdate(极少使用)

class App extends React.Component {
  // 构造器
  constructor(props) {
    console.log('constructor')
    super(props)
    this.state = {
      count: 0
    }
  }
  // getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。
  // 此生命周期方法的任何返回值将作为参数传递给 componentDidUpdate()。
  // componentDidUpdate必须存在
  // 更新前获取快照
  getSnapshotBeforeUpdate() {
    console.log('getSnapshotBeforeUpdate')
    return 'getSnapshotBeforeUpdate'
  }
  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log('componentDidUpdate', prevProps, prevState, snapshot)
  }

  // 组件渲染
  render () {
    console.log('render')
    return (
      <div>
      React声明周期
      <div>{this.state.count}</div>
      <button onClick={() => this.change()}>change</button>
      </div>
    )
  }
  change() {
    const count = this.state.count
    this.setState({ count: count + 1 })
  }
}