React学习(九)组件的生命周期(新)



一、React组件生命周期(新)

1.流程图

在这里插入图片描述

2.即将废弃的三个钩子

componentWillUpdate
componentWillMount
componentWillReceiveProps
前面应加上UNSAFE_

3.新增加的钩子

(1)getDerivedStateFromProps

         前面要加static,必须要返回状态对象或null,能接收props,state
         适用于state的值在任何时候都取决于props的情况
<!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>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <!-- 生产环境中不建议使用 -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
    <!-- 引入prop-types,用于对标签属性进行限制 -->
    <!-- <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script> -->
    <script type="text/babel">
        // 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
        class Count extends React.Component {
            // 1.1构造器
            constructor(props){
                console.log("Count-constructor")
                super(props)
            // 初始化状态
                this.state ={count:0}
            }
            // 加1按钮回调
            add=()=>{
                // 获取原状态
                const{count}=this.state
                this.setState({count:count+1})
            }
            // 卸载组件
            death=()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            // 强制更新
            force=()=>{
                this.forceUpdate()
            }
            // 前面要加static,必须要返回状态对象或null,能接收props,state
            // 适用于state的值在任何时候都取决于props的情况
            static getDerivedStateFromProps=(props,state)=>{
                console.log("getDerivedState")
                return props
            }
            // 1.4组件挂载完毕的钩子
            componentDidMount(){
                console.log("Count-componentDidMount")
            }
            // 1.5组件将要卸载的钩子
            componentWillUnmount(){
                console.log("Count-componentWillUnmount")
            }
            // 2.1控制组件更新的阀门,默认返回值为真,返回值为真时可以更新,为假时状态不可以更新
            shouldComponentUpdate(){
                console.log("Count-shouldComponentUpdate")
                return false
            }
            // 2.3组件更新完毕的钩子
            componentDidUpdate(){
                console.log("Count-componentDidUpdate")
            }
            //1.3 render调用的时机:初始化渲染,状态更新之后
            render(){
                console.log("Count-render")
                const {count}=this.state
                return (
                    <div>
                        <h2 >当前求和为:{count}</h2>
                        <button onClick={this.add}>点我加一</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Count/>,document.getElementById('test'))
    </script>
</body>
</html> 

(2)getSnapshotBeforeUpdate()

在更新之前获取快照
getsnapshotBefopdate(prevProps, prevstate)
getsnapshotBeforeupdate()在最近一次渲染输出(提交到 DOM 节点)之前调用。它便得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任同返回值将作为参数传递给 componentDidUpdate().
此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。
组件更新完毕的钩子componentDidUpdate()能够接收三个参数,
preProps为之前的props,preState为之前的状态的,snapshotValue为getSnapshotBeforeUpdate组件的返回值 componentDidUpdate(preProps,preState,snapshotValue)

<!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>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <!-- 生产环境中不建议使用 -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
    <!-- 引入prop-types,用于对标签属性进行限制 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
    <script type="text/babel">
        // 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
        class Count extends React.Component {
            // 1.1构造器
            constructor(props){
                console.log("Count-constructor")
                super(props)
            // 初始化状态
                this.state ={count:0}
            }
            // 加1按钮回调
            add=()=>{
                // 获取原状态
                const{count}=this.state
                this.setState({count:count+1})
            }
            // 卸载组件
            death=()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            // 强制更新
            force=()=>{
                this.forceUpdate()
            }
            // 前面要加static,必须要返回状态对象或null,能接收props,state
            // 适用于state的值在任何时候都取决于props的情况
            static getDerivedStateFromProps=(props,state)=>{
                console.log("getDerivedState")
                return null
            }
            // 在更新之前获取快照
            getSnapshotBeforeUpdate=()=>{
                console.log('getSnapshotBeforeUpdate')
                return null
            }
            // 1.4组件挂载完毕的钩子
            componentDidMount(){
                console.log("Count-componentDidMount")
            }
            // 1.5组件将要卸载的钩子
            componentWillUnmount(){
                console.log("Count-componentWillUnmount")
            }
            // 2.1控制组件更新的阀门,默认返回值为真,返回值为真时可以更新,为假时状态不可以更新
            shouldComponentUpdate(){
                console.log("Count-shouldComponentUpdate")
                return true
            }
            // 2.3组件更新完毕的钩子, 能够接收三个参数
            componentDidUpdate(preProps,preState,snapshotValue){
                console.log("Count-componentDidUpdate",preProps,preState,snapshotValue)
            }
            //1.3 render调用的时机:初始化渲染,状态更新之后
            render(){
                console.log("Count-render")
                const {count}=this.state
                return (
                    <div>
                        <h2 >当前求和为:{count}</h2>
                        <button onClick={this.add}>点我加一</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
                    </div>
                )
            }
        }
        // const container = document.getElementById('test')
        // const root = createRoot(container)
        // root.render(<Count/>)
        ReactDOM.render(<Count count={199}/>,document.getElementById('test'))
    </script>
</body>
</html> 

使用案例
复习

<!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{
            width: 200px;
            height: 150px;
            background-color: skyblue;
            overflow: auto;
        }
        .news{
            height:30px;
        }
    </style>
</head>
<body>
    <div id= 'test'></div>
    <div class ='list'>
        <div class='news'>新闻1</div>
        <div class='news'>新闻2</div>
        <div class='news'>新闻3</div>
        <div class='news'>新闻4</div>
        <div class='news'>新闻5</div>
        <div class='news'>新闻6</div>
    </div>
    
    <script type="text/javascript">
        const list = document.getElementsByClassName('list')[0]
        // 向下滚动30px
        list.scrollTop=30
        // 内容区的高度180
        console.log(list.scrollHeight)
    </script>
</body>
</html> 

react案例
实现每隔1秒出现一条新闻,滑动时,新闻会停在当前页面,但是新闻依旧会不断增加

<!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: 150px;
            width: 200px;
            background-color:skyblue;
            overflow: auto;
        }
        .news{
            height:30px;
        }
    </style>
</head>
<body>
    <div id= 'test'></div>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <!-- 生产环境中不建议使用 -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
    <!-- 引入prop-types,用于对标签属性进行限制 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
    <script type="text/babel">
        // 生命周期回调函数=生命周期钩子函数=生命周期函数=生命周期钩子
        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() { 
                // console.log(this.refs.list.scrollHeight)
                return this.refs.list.scrollHeight
            }
            componentDidUpdate(preProps,preState,height) {
                // console.log(height)
                // console.log(this.refs.list.scrollTop)
                this.refs.list.scrollTop+=this.refs.list.scrollHeight-height

            }
            //1.3 render调用的时机:初始化渲染,状态更新之后
            render(){

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

总结

提示:这里对文章进行总结:

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()触发

componentWillUnmount()

常用,一般做一些收尾的事,例如:关闭定时器,取消订阅消息

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值