React生命周期小练习getSnapshotBeforeUpdate和componentDidUpdate配合使用

目标: 每隔一秒生成一条新闻


<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>Demotitle>
  <style>
    .list {
      
      width: 200px;
      height: 150px;
      background: skyblue;
      overflow: auto;
    }
    .list ul {
      
      margin: 0;
      padding: 0;
    }

    .list li {
      
      list-style: none;
      height: 30px;
    }
  style>
head>
<body>
  <div id="newslist">div>
  
  <script type="text/javascript" src="../js/react.development.js">script>
  
  <script type="text/javascript" src="../js/react-dom.development.js">script>
  
  <script type="text/javascript" src="../js/babel.min.js">script>
  
  <script type="text/javascript" src="../js/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)
      }

      render () {
      
        return (
          <div className="list">
            <ul>
              {
      
                this.state.newsArr.map((n) => {
      
                  return <li>{
      n}</li>
                })
              }
            </ul>
          </div>
        )
      }
    }

    ReactDOM.render(<NewsList />, document.getElementById('newslist'))
  script>
body>
html>

看一下效果:
React生命周期小练习getSnapshotBeforeUpdate和componentDidUpdate配合使用_第1张图片
效果是出来了,但是控制台有报错:
在这里插入图片描述
修改一下:
React生命周期小练习getSnapshotBeforeUpdate和componentDidUpdate配合使用_第2张图片
现在我么想实现,比如我想看第10条新闻,但是又不想源源不断的新闻把第10条新闻挤上去,怎么办?
这时候就用到getSnapshotBeoreUpdate了:
React生命周期小练习getSnapshotBeforeUpdate和componentDidUpdate配合使用_第3张图片
getSnapshotBeforeUpdate返回更新前的list的高度,传给componentDidUpdatecomponentDidUpdate里面通过第三个参数接收到更新前的高度,获取更新后的高度,获取这两次之间的差值高度,这个高度就代表在着这次要下移多少个单位,所以左边用this.refs.list.scrollTop +=赋值
React生命周期小练习getSnapshotBeforeUpdate和componentDidUpdate配合使用_第4张图片
源码:


<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>Demotitle>
  <style>
    .list {
      
      width: 200px;
      height: 150px;
      background: skyblue;
      overflow: auto;
    }
    .list ul {
      
      margin: 0;
      padding: 0;
    }

    .list li {
      
      list-style: none;
      height: 30px;
    }
  style>
head>
<body>
  <div id="newslist">div>
  
  <script type="text/javascript" src="../js/react.development.js">script>
  
  <script type="text/javascript" src="../js/react-dom.development.js">script>
  
  <script type="text/javascript" src="../js/babel.min.js">script>
  
  <script type="text/javascript" src="../js/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('getSnapshotBeoreUpdate')
        // scrollHeight是目标内容区高度 getSnapshotBeoreUpdate中return的东西可以在componentDidUpdate里接收
        return this.refs.list.scrollHeight
      }

      componentDidUpdate (prevProps, prevState, height) {
      
        console.log('componentDidUpdate')
        // scrollTop有点类似于margin-top的效果
        this.refs.list.scrollTop += this.refs.list.scrollHeight - height
      }

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

    ReactDOM.render(<NewsList />, document.getElementById('newslist'))
  script>
body>
html>

你可能感兴趣的:(react,javascript,react)