React-生命周期

256 阅读2分钟

新版生命周期

  • componentWillMount:在渲染前调用。

  • componentDidMount:在第一次渲染后调用(发起Ajax请求)

  • componentWillReceiveProps:在组件接收到一个新的props时被调用。这个方法在第一次渲染时不会被调用。

  • shouldComponentUpdate:返回一个布尔值。在组件接收到新的props或state时被调用。在初始化时或者使用forceUpdate时不被调用。可以在你确认不需要更新组件时使用。

  • componentWillUpdate:在组件接收到新的props或state,但还没有render时被调用。在初始化时不会被调用。

  • componentDidUpdate:在组件完成更新后立即调用。在初始化时不会被调用。

  • componentWillUnmount 在组件从DOM中移除的时候立刻被调用。


import React from "react"
import ReactDOM from "react-dom"

class Counter extends React.Component{
    static defaultProps = {name:"wangcai"} // 默认属性
    constructor(props){
        super(props)
        this.state = {number:0} 
    }
    UNSAFE_componentWillMount(){
        console.log("Counter: componentWillMount") 
    }
    shouldComponentUpdate(nextProps,nextState){
        console.log("Counter: shouldComponentUpdate") 
        return true;
    }
    componentWillUpdate(){
        console.log("Counter: componentWillUpdate") 
    }
    componentDidUpdate(){
        console.log("Counter: componentDidUpdate") 
    }
    handleClick = ()=>{
        this.setState({number:this.state.number+1})
    }
    render(){
        console.log("Counter: render")  // 2
        return(
            <div>
                <h1>父组件</h1>
                <p>{this.state.number}</p>
                <button onClick={this.handleClick}>+</button>
                <hr/>
                {this.state.number%2==0 ? <SubCounter number={this.state.number}></SubCounter> : null}
            </div>
        )
    }
    componentDidMount(){
        console.log("Counter: componentDidMount") // 3
    }
}

class SubCounter extends React.Component{
    UNSAFE_componentWillMount(){
        console.log("SubCounter: componentWillMount") // 1
    }
    componentDidMount(){
        console.log("SubCounter: componentDidMount") // 3
    }
    componentWillReceiveProps(){
        console.log("SubCounter: componentWillReceiveProps")
    }
    shouldComponentUpdate(){
        console.log("SubCounter: shouldComponentUpdate")
        // return false;
        return true;
    }
    componentWillUpdate(){
        console.log("SubCounter: componentWillUpdate") // 
    }
    componentDidUpdate(){
        console.log("SubCounter: componentDidUpdate") 
    }
    render(){
        console.log("SubCounter: render")
        return(
            <div>
                <h1>子组件</h1>
                <p>{this.props.number}</p>
            </div>
        )
    }
    componentWillUnmount(){
        console.log("SubCounter: componentWillUnmount") 
    }
}
ReactDOM.render(<Counter />, window.app)

新版生命周期

getDerivedStateFromProps:将接收的属性变成自身的状态,并且可以修改状态,是一个静态函数,所以函数体内不能访问this,简单说,就是应该一个纯函数,输出完全由输入决定。

import React from "react";
import ReactDOM from "react-dom";
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };
  }
  handleClick = () => {
    this.setState({ number: this.state.number + 1 });
  };
  render() {
    return (
      <div>
        <h1>父组件</h1>
        <p>{this.state.number}</p>
        <button onClick={this.handleClick}>+</button>
        <hr />
        <SubCounter number={this.state.number}></SubCounter>
      </div>
    );
  }
}
class SubCounter extends React.Component {
  state = {
    number: 0
  };
  static getDerivedStateFromProps(nextProps, prevState) {
    // console.log("nextProps: ",nextProps)  // {number: 0}
    let { number } = nextProps;
    return { number };
  }
  render() {
    return (
      <div>
        <h1>子组件</h1>
        <p>{this.state.number}</p>
      </div>
    );
  }
}
ReactDOM.render(<Counter />, window.app);

getSnapshotBeforeUpdate:获取更新之前DOM的快照,getSnapshotBeforeUpdate中返回了一个值,这个值会给componedDidUpdate的最后一个参数

    import React from "react"
import ReactDOM from "react-dom"
class News extends React.Component{
    constructor(props){
        super(props)
        this.scrollRef = React.createRef();
    }
    state = {
        news:[]
    }
    componentDidMount(){
        this.timer = setInterval(()=>{
            this.setState({
                news:[`${this.state.news.length}`,...this.state.news]
            })
        },1000)
    }
    componentWillUnmount(){
        clearInterval(this.timer)
    }
    // 获取更新之前dom的快照
    getSnapshotBeforeUpdate(){
        return this.scrollRef.current.scrollHeight;
    }
    componentDidUpdate(prevProps,prevState,lastScrollHeight){
        let scrollTop = this.scrollRef.current.scrollTop; 
        this.scrollRef.current.scrollTop = scrollTop+(this.scrollRef.current.scrollHeight-lastScrollHeight)
    }
    render(){
        let styles = {
            height:"100px",
            width:"200px",
            border:"1px solid red",
            overflow:"auto"
        }
        return(
            <ul style={styles} ref={this.scrollRef}>
               {
                   this.state.news.map((item,index)=><li key={index}>{item}</li>)
               }
            </ul>
        )
    }
}
ReactDOM.render(<News />, window.app)

原文链接:blog.csdn.net/weixin_4010…