44.B站 react的生命周期(旧) - yiqunkeke/react-jianshu-shangguigu-zty GitHub Wiki

<!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>hello_react</title>
    <!-- 引入react,为了使用 React对象  -->
    <script src="js/react.development.js"></script>
    <!-- 引入 react-dom, 为了使用 ReactDOM 对象 -->
    <script src="js/react-dom.development.js"></script>
    <!-- 引入 babel, 为了 解析 JSX -->
    <script src="js/babel.min.js"></script>
    <!-- 引入prop-types,为了对 props属性的类型、必要性、默认值进行限制,全局多了一个 PropTypes对象 -->
    <script src="js/prop-types.js"></script>
</head>
<body>
    <div id="test"></div>

    <!-- 1.引出生命周期 -->
    <!-- <script type="text/babel">
        class Life extends React.Component {

            state = {
                opacity: 1
            }

            // death是通过onClick事件的回调使用----》所以必须写成赋值语句+箭头函数形式---》目的是让death中的this指向组件实例对象
            death = () => {
                // 清除定时器
                // clearInterval(this.timer)
                // 卸载组件
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            // 报错:类里面不能随便写代码。
            // 类里面可以写什么:构造器、方法、static、赋值语句
            // setInterval(() => {
                
            // }, 200);

            // action = () => {
            //     setInterval(() => {
            //         let { opacity } = this.state
            //         opacity -= 0.1
            //         if( opacity <= 0) opacity = 1 

            //         this.setState({ opacity})
            //     }, 200);
            // }
            
            // 这个函数是通过Lift的实例对象.调用的。
            // 什么时候调用?-----组件挂载完毕
            componentDidMount() {
                this.timer = setInterval(() => {
                    let { opacity } = this.state
                    opacity -= 0.1
                    if( opacity <= 0) opacity = 1

                    this.setState({ opacity})
                }, 200);
            }

            // 组件将要卸载
            componentWillUnmount() {
                clearInterval(this.timer)
            }

            // render调用的时机:初始化渲染、状态更新后
            render() {
                console.log('render')

                // setInterval(() => {
                //     // 获取原状态
                //     let { opacity } = this.state
                //     // 减小0.1
                //     opacity -= 0.1
                //     // opacity可能为负数、  在js中: 0.1 + 0.2 !==0.3、  所以if判断条件写成 <=0,而不写 == 0
                //     if( opacity <= 0) opacity = 1
                //     // 设置新的透明度
                //     this.setState({ opacity})
                // }, 200);
                
                // 在render中写setState ===》 引发了无限递归  ===》所以定时器写在render中不合适
                // 办法:加个“开始变化”按钮,触发定时器

                return (
                    <div>
                        <h2 style={{opacity: this.state.opacity}}>React 学不会怎么办?</h2>
                        <button onClick={this.death}>不活了</button>
                        {/*<button onClick={this.action}>开始变化</button>*/}
                    </div>
                )
            }
    
        }
        
        // react一直在一些合适的时间点,干一些合适的事情。
        // 生命周期回调函数:你只管写这些函数,react会在合适的时间点帮你自动调用这些函数,所以叫生命周期【回调函数】。因为这些函数是你定义的,但是你没有调用,是react帮你调用的。
        // 生命周期回调函数《===》生命周期钩子函数 《===》 生命周期函数 《===》生命周期钩子
        ReactDOM.render(<Life/>, document.getElementById('test'))
    </script> -->

    <!-- 2.生命周期回调函数【旧】 -->
    <!-- 生命周期调用顺序与代码书写顺序有关系吗? ----没有关系。 -->
    <!-- 挂载时:
        ===》 constructor ===》 componentWillMount ===》 render ===》 componentDidMount ===》 componentWillUnmount
    -->
    <!-- 更新时:
        ===》 setState() 正常更新===》 shouldComponentUpdate 阀门 ===》 componentWillUpdate ===》 render ===》 componentDidUpdate ===》 componentWillUnmount

        ===》 forceUpdate() 强制更新===》 componentWillUpdate ===》 render ===》 componentDidUpdate ===》 componentWillUnmount
        
        强制更新绕过了阀门。

    -->
    <!-- <script type="text/babel">
        // 创建组件
        class Count extends React.Component {

            // 【挂载时】构造器---1
            constructor(props) {
                console.log('Count---constructor')
                super(props)
                this.state = {count: 0}
            }

            add = () => {
                let {count} = this.state
                // 【更新时】 setState()---(1)
                this.setState({count: count+1})
            }

            death = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            force = () => {
                this.forceUpdate()
            }

            // 【挂载时】组件将要挂载---2
            componentWillMount() {
                console.log('Count---componentWillMount')
            }

            // 【挂载时】组件挂载完毕---4
            componentDidMount() {
                console.log('Count---componentDidMount')
            }

            // 组件将要卸载 --- 5
            componentWillUnmount() {
                console.log('Count---componentWillUnmount')
            }

            // 【更新时】 组件是否更新---(2)    默认返回true、控制组件更新的阀门
            shouldComponentUpdate() {
                console.log('Count---shouldComponentUpdate')
                return true
            }

            // 【更新时】 组件将要更新---(3)
            componentWillUpdate() {
                console.log('Count---componentWillUpdate')
            }

            // 【更新时】 组件更新完毕---(5)
            componentDidUpdate() {
                console.log('Count---componentDidUpdate')
            }

            // 【挂载时】挂载---3
            // 【更新时】更新---(4)
            render() {
                console.log('Count---render')
                const {count} = this.state
                return (
                    <div>
                        <h2>当前求和为{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'))
    </script> -->

    <!-- 更新时:
        ===》 父组件重新render ===》 componentWillReceiveProps===》 shouldComponentUpdate 阀门 ===》 componentWillUpdate ===》 render ===》 componentDidUpdate ===》 componentWillUnmount
    -->
    <script type="text/babel">
        // 创建组件
        class A extends React.Component {

            state = {
                carName: '奔驰'
            }

            changeCar = () => {
                this.setState({carName: '奥托'})
            }

            render() {
                return (
                   <div>
                        <div>我是A组件</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName}/>
                    </div>
                )
            }
        }

        class B extends React.Component {

            // 组件将要接收props---(1)
            // 注意:这里有个坑,第一次传的props不算。
            componentWillReceiveProps(props) {
                console.log('B---componentWillReceiveProps', props)
            }

            // 【更新时】 组件是否更新---(2)    默认返回true、控制组件更新的阀门
            shouldComponentUpdate() {
                console.log('B---shouldComponentUpdate')
                return true
            }

            // 【更新时】 组件将要更新---(3)
            componentWillUpdate() {
                console.log('B---componentWillUpdate')
            }

            // 【更新时】 组件更新完毕---(5)
            componentDidUpdate() {
                console.log('B---componentDidUpdate')
            }

            // 【更新时】更新---(4)
            render() {
                console.log('B---render')
                return (
                   <div>
                    我是B 组件,接收到的车是:{this.props.carName}
                   </div>
                )
            }
        }

        // 挂载组件
        ReactDOM.render(<A/>,document.getElementById('test'))
    </script>
    
    <!-- 3. 总结生命周期 
        生命周期分为三个阶段:
        1. 初始化阶段---由ReactDOM.render触发--初次渲染
            constructor---componentWillMount----render----componentDidMount
        2. 更新阶段----由组件内部this.setState() 或者 父组件render 触发
            shouldComponentUpdate --- componentWillUpdate---render---componentDidUpdate 
            强制更新 forceUpdate 没有阀门。
        3. 卸载组件--由ReactDOM.unmountComponentAtNode() 触发
            componentWillUnmount

        常用的有: componentDidMount 适用于页面一上来做点什么事情。一般做一些初始化的事情。例如:开启定时器、发送网络请求、订阅消息
                  componentWillUnmount 收尾的事情:关闭定时器、取消订阅消息  
                  render  必须要用
    -->
    
</body>
</html>
⚠️ **GitHub.com Fallback** ⚠️