学无先后,达者为师

网站首页 编程语言 正文

react组件的生命周期

作者:二脸懵逼 更新时间: 2022-07-30 编程语言

react组件的生命周期

  • 1、什么是生命周期?
  • 2、生命周期流程图(旧)
      • 2.1 、生命周期的三个阶段(旧)
  • 3、生命周期流程图(新)
      • 3.1、被弃用的三个钩子函数
      • 3.2、生命周期的三个阶段(新)

需求:定义组件实现以下功能:

  1. 让指定的文本做显示 / 隐藏的渐变动画
  2. 从完全可见,到彻底消失,耗时2S
  3. 点击“不活了”按钮从界面中卸载组件
 //1、创建组件
    class Demo extends React.Component {
        state = {opacity: 1}
        death = () => {
            //卸载组件
            ReactDOM.unmountComponentAtNode(document.getElementById('test'))
        }
        //组件完成挂载后执行
        componentDidMount() {
            this.timer=setInterval(() => {
                //    获取原状态
                let {opacity} = this.state;
                //    减小0.1
                opacity -= 0.1
                if (opacity <= 0) opacity = 1
                this.setState({opacity})
            }, 200)
        }

        //组件将要卸载时调用
        componentWillUnmount(){
            //清除定时器
            clearInterval(this.timer)
        }
        //render调用时机:初始化渲染、状态更新之后
        render() {
            return (
                <div>
                    <h1 style={{opacity: this.state.opacity}}>react感觉还是有点难滴!!!怎么办?</h1>
                    <button onClick={this.death}>不活了</button>
                </div>
            )
        }
    }

    //2、渲染虚拟DOM
    ReactDOM.render(<Demo/>, document.getElementById('test'))

1、什么是生命周期?

  1. 组件从创建到死亡它会经历一些特定的阶段。
  2. React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。
  3. 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作

2、生命周期流程图(旧)

在这里插入图片描述

2.1 、生命周期的三个阶段(旧)

  1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
    1. constructor()
    2. componentWillMount()
    3. render()
    4. componentDidMount()---------常用,一般在这个钩子函数做一些初始化操作,例如:开启定时器,发起网络请求,订阅消息等等…
  2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
    1. shouldComponentUpdate()
    2. componentWillUpdate()
    3. render()--------必须使用的一个
    4. componentDidUpdate()
  3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
    1. componentWillUnmount()--------常用,一般在这个钩子函数做一些收尾的事儿,例如:关闭定时器、取消定时器…
 //1、创建组件
    class Count extends React.Component {
        //构造器
        constructor(props) {
            console.log('count-constructor');
            super(props);
            this.state = {count: 0}
        }

        //将要挂载
        componentWillMount() {
            console.log('count-componentWillMount');
        }

        //挂载后
        componentDidMount() {
            console.log('count-componentDidMount');
        }

        //将要卸载
        componentWillUnmount() {
            //清除定时器
            console.log('count-componentWillUnmount');
        }

        //控制组件是否更新的”阀门“
        shouldComponentUpdate() {
            console.log('count-shouldComponentUpdate');
            return true;//返回false状态无法更新,返回值为true,则更新
        }

        //组件将要更新
        componentWillUpdate() {
            console.log('count-componentWillUpdate');
        }

        //组件更新完成
        componentDidUpdate() {
            console.log('count-componentDidUpdate');
        }

        //count+1
        add = () => {
            //    获取原状态
            let {count} = this.state;
            this.setState({
                count: count + 1
            })
        }
        //卸载组件
        unmount = () => {
            ReactDOM.unmountComponentAtNode(document.getElementById('test'))
        }
        //强制更新
        force = () => {
            //强制更新(无  控制组件是否更新的‘阀门’的步骤)
            this.forceUpdate();
        }

        render() {
            console.log('count-render');
            let {count} = this.state;
            return (
                <div>
                    <h1>当前求和为:{count}</h1>
                    <button onClick={this.add}>点击+1</button>
                    <button onClick={this.unmount}>卸载组件</button>
                    <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
                </div>
            )
        }
    }

    //父组件
    class Father extends React.Component {
        state = {carName: '宝马'}
        changeCar = () => {
            this.setState({
                carName: '马自达'
            })
        }

        render() {
            return (<div>
                    <div>Father</div>
                    <button onClick={this.changeCar}>换车</button>
                    <Child carName={this.state.carName}></Child>
                </div>
            )
        }
    }

    //子组件
    class Child extends React.Component {
        //组件将要接收父组件传过来的新的属性值(第一次不会执行)
        componentWillReceiveProps(props) {
            console.log('Child-componentWillReceiveProps',props);
        }

        render() {
            return (<div>我是Child组件,我从Father组件中接收到的车是:{this.props.carName}</div>)
        }
    }

    //2、渲染虚拟DOM
    // ReactDOM.render(<Count/>, document.getElementById('test'))
    ReactDOM.render(<Father/>, document.getElementById('test'))

3、生命周期流程图(新)

在这里插入图片描述

3.1、被弃用的三个钩子函数

    1. componentWillMount
    1. componentWillReceiveProps
    1. componentWillUpdate

  现在使用会出现警告,需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。

3.2、生命周期的三个阶段(新)

  1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
    1. constructor()
    2. getDerivedStateFromProps
    3. render()
    4. componentDidMount()---------常用,一般在这个钩子函数做一些初始化操作,例如:开启定时器,发起网络请求,订阅消息等等…
  2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
    1. getDerivedStateFromProps
    2. shouldComponentUpdate()
    3. render()
    4. getSnapshotBeforeUpdate
    5. componentDidUpdate()
  3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
    1. componentWillUnmount()--------常用,一般在这个钩子函数做一些收尾的事儿,例如:关闭定时器、取消定时器…
    //1、创建组件
    class Count extends React.Component {
        //构造器
        constructor(props) {
            console.log('count-constructor');
            super(props);
            this.state = {count: 0}
        }

        // 若state的值在任何时候都取决于props,可以使用
        //派生状态(state的值在任何时候都取决于props.派生状态会导致代码冗余,并使组件难以维护)
        static getDerivedStateFromProps(props, state) {
            //必须有返回值,null或state obj状态对象
            console.log('count-getDerivedStateFromProps', props, state);
            return null;
            // return props;//返回状态对象会影响状态的更新
        }

        getSnapshotBeforeUpdate(prevProps, prevState) {
            console.log('count-getSnapshotBeforeUpdate', prevProps, prevState);
            return 'xiao';
        }
        //挂载后
        componentDidMount() {
            console.log('count-componentDidMount');
        }

        //将要卸载
        componentWillUnmount() {
            //清除定时器
            console.log('count-componentWillUnmount');
        }

        //控制组件是否更新的”阀门“
        shouldComponentUpdate() {
            console.log('count-shouldComponentUpdate');
            return true;//返回false状态无法更新,返回值为true,则更新
        }

        //组件更新完成(第三个参数为getSnapshotBeforeUpdate钩子函数的返回值)
        componentDidUpdate(prevProps, prevState,snapshotValue) {
            console.log('count-componentDidUpdate',prevProps, prevState,snapshotValue);
        }

        //count+1
        add = () => {
            //    获取原状态
            let {count} = this.state;
            this.setState({
                count: count + 1
            })
        }
        //卸载组件
        unmount = () => {
            ReactDOM.unmountComponentAtNode(document.getElementById('test'))
        }

        render() {
            console.log('count-render');
            let {count} = this.state;
            return (
                <div>
                    <h1>当前求和为:{count}</h1>
                    <button onClick={this.add}>点击+1</button>
                    <button onClick={this.unmount}>卸载组件</button>
                </div>
            )
        }
    }

    //2、渲染虚拟DOM
    ReactDOM.render(<Count count="99"/>, document.getElementById('test'))

getSnapshotBeforeUpdate的应用场景:

  以特殊方式处理滚动位置

 //1、创建组件
    class NewsList extends React.Component {
        state = {newsArr: []}

        componentDidMount() {
            setInterval(() => {
                //    获取原来的状态值
                const {newsArr} = this.state;
                //    模拟一条新闻
                const news = '新闻' + (newsArr.length + 1);
                //    更新状态
                this.setState({
                    newsArr: [news, ...newsArr]
                })
            }, 1000)
        }

        getSnapshotBeforeUpdate() {
            return this.refs.list.scrollHeight
        }

        componentDidUpdate(prevProps, prevState, snapshotValue) {
            this.refs.list.scrollTop += this.refs.list.scrollHeight - snapshotValue;
        }

        render() {
            return (
                <div className="list" ref="list">
                    {this.state.newsArr.map((item, index) => {
                        return <div className="news" key={index}>{item}</div>
                    })}
                </div>
            )
        }
    }

    ReactDOM.render(<NewsList/>, document.getElementById('test'))

原文链接:https://blog.csdn.net/fangqi20170515/article/details/126052535

栏目分类
最近更新