React学习笔记【6】(React生命周期)

学习地址:https://www.bilibili.com/video/BV1wy4y1D7JT
官方文档:

生命周期理解

  • 组件从创建到注销经历的一些特定阶段。
  • React组件包含一系列钩子函数(生命周期回调函数),在特定的时刻调用。
  • 在定义组件时会在特定的生命周期回调函数中做特定的工作。

生命周期流程图(旧)【注意引入库的版本号】
生命周期流程图(旧)
生命周期流程图(新)【注意引入库的版本号】
生命周期流程图(新)
重要的钩子

  1. render():初始化渲染或更新渲染时调用
  2. componentDidMount():组件挂载完毕,开启监听,发送请求
  3. componentWillUnmount():组件将要卸载的钩子,做一些收尾工作如清除定时器

即将废弃的钩子
此三个钩子函数在新版本中会在控制台显示警告,需添加‘UNSAFF_’前缀方可使用,以后可能会彻底废弃,不建议使用

  1. componentWillMount():组件将要挂载的钩子
  2. componentWillReveiceProps():组件将要接收新的props的钩子
  3. componentWillUpdate():组件将要更新的钩子

生命周期的三个阶段(旧版本)

  1. 初始化阶段:由ReactDOM.render()触发----初次渲染
    • constructor() 构造器
    • componentWillMount() 组件将要挂载
    • render()
    • componentDidMount() 组件挂载完毕
  2. 更新阶段:由组件内部this.setState()或父组件重新render()触发,this.forceUpdate()强制更新
    • componentWillReveiceProps() 组件将要接受新的props的钩子,父组件重新render时触发
    • shouldComponentUpdate() 控制组件更新的‘阀门’,返回一个布尔值,true表示可更新,false表示不可更新。强制更新不受此返回值的影响,即使返回false依然更新。
    • componentWillUpdate() 组件将要更新
    • render()
    • componentDidUpdate() 组件更新完毕
  3. 卸载组件:由ReactDOM.unmountComponentAtNode()触发
    • componentWillUnmount() 组件将要卸载

运行测试(旧版本生命周期)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="test"></div>

    <div id="test2"></div>

    <!-- react核心库 -->
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <!-- react-dom用于支持react操作dom -->
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <!-- 引入babel 用于将jsx转成js -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.js"></script>
    <script type="text/babel">
        class Count extends React.Component {
            // 构造器
            constructor(props) {
                console.log('count--constructor')
                super(props);
                // 初始化状态
                this.state = { count: 0 }
            }

            // +1按钮的回调
            add = () => {
                let { count } = this.state;
                this.setState({ count: count + 1 })
            }
            // 卸载按钮的回调
            death = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById('test'));
            }
            // 强制更新的回调
            force = () => {
                this.forceUpdate()
            }

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

            // 组件挂载完毕
            componentDidMount() {
                console.log('count--componentDidMount')
            }
            // 组件将要卸载的钩子
            componentWillUnmount() {
                console.log('count--componentWillUnmount');
            }
            // 控制组件更新的‘阀门’,返回一个布尔值,true表示可更新,false表示不可更新
            shouldComponentUpdate() {
                console.log('count--shouldComponentUpdate');
                return true;
            }
            // 组件将要更新的钩子
            componentWillUpdate() {
                console.log('count--componentWillUpdate');
            }

            // 组件更新完毕的钩子
            componentDidUpdate() {
                console.log('count--componentDidUpdate');
            }

            render() {
                console.log('count--render')
                return (
                    <div>
                        <h2>当前求和为{this.state.count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>点击按钮强制更新,不修改状态</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Count />, document.getElementById('test'));


        class A extends React.Component {
            state={carName:'aaa'}
            change=()=>{
                this.setState({carName:'bbb'})
            }
            render() {
                return (
                    <div>
                        <div>
                            组件A
                        </div>
                        <button onClick={this.change}>改变</button>
                        <B carName={this.state.carName} />
                    </div>
                )
            }
        }

        class B extends React.Component {
            componentWillReceiveProps(props){
                console.log('B--componentWillReceiveProps',props)
            }
            render() {
                return (
                    <div>
                        组件B,接收到的参数:{this.props.carName}
                    </div>
                )
            }
        }

        ReactDOM.render(<A />,document.getElementById('test2'))
    </script>
</body>

</html>

生命周期的三个阶段(新版本)

  1. 初始化阶段:由ReactDOM.render()触发----初次渲染
    • constructor() 构造器
    • static getDerivedStateFromProps()
    • render()
    • componentDidMount() 组件挂载完毕
  2. 更新阶段:由组件内部this.setState()或父组件重新render()触发,this.forceUpdate()强制更新
    • static getDerivedStateFromProps()
    • shouldComponentUpdate() 控制组件更新的‘阀门’,返回一个布尔值,true表示可更新,false表示不可更新。强制更新不受此返回值的影响,即使返回false依然更新。
    • render()
    • getSnapshotBeforUpdate() 使组件在可能发生更改之前获取一些信息(如滚动位置),此生命周期返回的任何值豆浆作为参数传递给componentDidUpdate()。
    • componentDidUpdate() 组件更新完毕
  3. 卸载组件:由ReactDOM.unmountComponentAtNode()触发
    • componentWillUnmount() 组件将要卸载

测试代码(新版本)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="test"></div>

    <div id="test2"></div>

    <!-- react核心库 -->
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <!-- react-dom用于支持react操作dom -->
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <!-- 引入babel 用于将jsx转成js -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.js"></script>
    <script type="text/babel">
        class Count extends React.Component {
            // 构造器
            constructor(props) {
                console.log('count--constructor')
                super(props);
                // 初始化状态
                this.state = { count: 0 }
            }

            // +1按钮的回调
            add = () => {
                let { count } = this.state;
                this.setState({ count: count + 1 })
            }
            // 卸载按钮的回调
            death = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById('test'));
            }
            // 强制更新的回调
            force = () => {
                this.forceUpdate()
            }

            // 从props中得到一个派生状态 及当state中的值在任何时候都取决于props的时候,可以使用此钩子
            //派生状态会导致代码冗余,并使组件难以维护
            static getDerivedStateFromProps(props,state){
                console.log('count--getDerivedStateFromProps',props,state);
                return props
            }

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

            // 组件挂载完毕
            componentDidMount() {
                console.log('count--componentDidMount')
            }
            // 组件将要卸载的钩子
            componentWillUnmount() {
                console.log('count--componentWillUnmount');
            }
            // 控制组件更新的‘阀门’,返回一个布尔值,true表示可更新,false表示不可更新
            shouldComponentUpdate() {
                console.log('count--shouldComponentUpdate');
                return true;
            }
            // 组件将要更新的钩子
            // UNSAFF_componentWillUpdate() {
            //     console.log('count--componentWillUpdate');
            // }

            // 组件更新完毕的钩子
            componentDidUpdate() {
                console.log('count--componentDidUpdate');
            }

            render() {
                console.log('count--render')
                return (
                    <div>
                        <h2>当前求和为{this.state.count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>点击按钮强制更新,不修改状态</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Count />, document.getElementById('test'));


        class A extends React.Component {
            state = { carName: 'aaa' }
            change = () => {
                this.setState({ carName: 'bbb' })
            }
            render() {
                return (
                    <div>
                        <div>
                            组件A
                        </div>
                        <button onClick={this.change}>改变</button>
                        <B carName={this.state.carName} />
                    </div>
                )
            }
        }

        class B extends React.Component {
            // UNSAFF_componentWillReceiveProps(props) {
            //     console.log('B--componentWillReceiveProps', props)
            // }
            render() {
                return (
                    <div>
                        组件B,接收到的参数:{this.props.carName}
                    </div>
                )
            }
        }

        ReactDOM.render(<A />, document.getElementById('test2'))
    </script>
</body>

</html>

getSnapshotBeforeUpdate钩子测试

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .list{
            height: 180px;
            background: skyblue;
            width: 200px;
            overflow: auto;
        }
        .news{
            height: 30px;
        }
    </style>
</head>

<body>
    <div id="test">

    </div>



    <!-- react核心库 -->
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <!-- react-dom用于支持react操作dom -->
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <!-- 引入babel 用于将jsx转成js -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.js"></script>

    <script type="text/babel">
        class NewsList extends React.Component {
            state = { newsList: [] }

            componentDidMount(){
                setInterval(() => {
                    let {newsList} = this.state;
                    let news = `新闻${newsList.length + 1}`;
                    this.setState({newsList:[news,...newsList]});
                }, 1000);
            }

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

            componentDidUpdate(preProps,preState,height){
                this.refs.list.scrollTop += this.refs.list.scrollHeight - height;
            }

            render() {
                return (
                    <div className="list" ref="list">
                        {this.state.newsList.map((item, index) => {
                            return <div key={index} className="news">{item}</div>
                        })}
                    </div>
                )
            }
        }
        ReactDOM.render(<NewsList />, document.getElementById('test'));
    </script>
</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值