D
D
darktowerk56c2019-10-08 19:01:46
React
darktowerk56c, 2019-10-08 19:01:46

How to make infinite scroll (redux)?

Continuing the topic:
How to make an infinite scroll with automatic content loading (React.js)?
Hello everyone, please tell me how to implement the following:
When the component is initialized, I have an ajax request in response, an array with ten objects comes in, for example, there are 10 of them.
When I scroll to the bottom of the page, in the onScroll method I will again make an ajax request, and from The database will receive the next ten records, and so on until all the data is retrieved from the database.
But now, it turns out that with each request, new data comes from the store, and when rendering, I overwrite the original books. How can I properly handle this situation?

import React, { useEffect } from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { getBooks } from '../../actions/book-actions'

const Books = (props) => {

  let page = ''

  const getParam = () => {
    const param = window.location.search
      .slice(window.location.search.indexOf('?') + 1)
      .split('&')

    let result = []

    for (let i = 0; i < param.length; i++) {
      let res = param[i].split('=')

      result[res[0]] = res[1]
    }

    if (result['page']) {
      page = result['page']
    } else {
      page = '1'
    }

    return param
  }

  getParam()

  let block = false

  const onScroll = () => {
    const windowHeight = window.innerHeight
    const documentHeight = document.body.clientHeight
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop

    if (windowHeight + scrollTop >= documentHeight && !block) {
      page++

      block = true

      props.getBooks({page}) // Вернуться данные с сервера
    }
  }

  window.addEventListener('scroll', onScroll)

  useEffect(() => {
    const page = {
      page: '1'
    }

    props.getBooks(page) // Вернуться данные с сервера
  }, [])

  const {book: {books, loading}} = props
  if (loading) return <p>loading</p>

  console.log('render')

  return (
    <div className="book">

      <table className="highlight">
        <thead>
        <tr>
          <th>Имя</th>
          <th>Город</th>
          <th>Номер телефона</th>
          <th/>
        </tr>
        </thead>

        <tbody>
        {
          books &&
          books.map((book) => {
            return (
              <tr key={book.pbnum}>
                <td>{book.pbfirstName} {book.pblastName}</td>
                <td>{book.pbcity}</td>
                <td>{book.pbphoneNumber}</td>
                <td/>
                <td>
                  <Link
                    className="waves-effect waves-light btn"
                    to={`/book/${book._id}/edit?allow=true`}
                  >Редактировать</Link>
                </td>
              </tr>
            )
          })
        }
        </tbody>
      </table>
    </div>
  )
}

Books.propTypes = {
  getBooks: PropTypes.func.isRequired
}

const mapDispatchToProps = {getBooks}

const mapStateToProps = state => ({
  book: state.book
})

export default connect(mapStateToProps, mapDispatchToProps)(Books)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Orbb, 2019-10-08
@darktowerk56c

save the previous result and add to it the coming
one I created in the state prevData = [];
all data coming to you prevData.push();
in render just mapish prevData.map();
there will be a loading effect. If the data is just a list with some info - up to ~300 lines in realtime works well.
ps and do not declare functions inside components, as you have done in Bux.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question