React的生命周期(新)

 

React的生命周期(新)

新生命周期新增的两个钩子:

 1. getDerivedStateFromProps :罕见的使用场景,如果state 的值在任何时候都取决于 props ,可以使用这个函数。但是代码会冗余,并且组件不好维护,不常使用。

 2. 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>4. getSnapshotBeforeUpdate的使用场景</title>
</head>
<style>
    .list {
        width: 200px;
        height: 150px;
        overflow: auto;
        background-color: skyblue;
    }
    .news {
        height: 30px;
    }
</style>
<body>
    <div id="list"></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://unpkg.com/babel-standalone@6.15.0/babel.min.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)
            }
            render() {
                return (
                    <div className="list" ref="list">
                        {
                            this.state.newsArr.map((n, index) => {
                                return <div className="news" key={index}>{n}</div>
                            })
                        }
                    </div>
                )
            }
            getSnapshotBeforeUpdate() {
                return this.refs.list.scrollHeight
            }
            componentDidUpdate(preProps, preState, height) {
                this.refs.list.scrollTop += this.refs.list.scrollHeight - height
            }
        }
        ReactDOM.render(<NewsList/>, document.getElementById('list'))
    </script>
</body>
</html>

效果如下图: 滚动条一直在缩短,内容在变长,但是列表是固定的,没有随着滚动条滚动

React的生命周期(新)

 

 

总结:     1. 初始化阶段: 由 ReactDOM.render() 触发 —— 初次渲染                  1. constructor()                  2. getDerivedStateFromProps                  3. render()                  4. componentDidMount() ===> 常用                      一般在这个钩子中做一些初始化的事情。例如:开启定时器、发送ajax请求、订阅消息    2. 更新阶段: 由组件内部 this.setState() 或父组件重新 render 触发                  1. getDerivedStateFromProps                  2. shouldComponentUpdate()                  3. render() ===> 常用                        初始化渲染或更新渲染调用                  4. getSnapshotBeforeUpdate()                  5. componentDidUpdate()        3. 卸载组件: 由 ReactDOM.unmountComponentAtNode() 触发                  1.  componentWillUnmount() ====> 常用                        一般在这个钩子中做一些收尾的事。例如:关闭定时器、取消订阅消息   即将废弃的钩子:   1. componentWillMount        2. componentWillReceiveProps        3. componentWillUpdate    现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。
上一篇:图片懒加载之echo.js


下一篇:02 为什么 React 16 要更改组件的生命周期?(上)