@darktowerk56c

Как сделать бесконечный скролл (redux)?

В продолжение темы:
Как правильно сделать бесконечный скролл с автоматической загрузкой контента (React.js)?
Всем привет, подскажите, пожалуйста, как реализовать следующее:
При инициализации компонента у меня происходит ajax запрос в ответе приходит массив с десятью объектами, например их 10.
Когда я скролл дойдет до низа страницы, в методе onScroll я снова сделаю ajax запрос, и из базы данных придет следующие десять записей, и так до тех пор, по не выведу все данные из БД.
Но сейчас, выходит, что при каждом запросе у меня из store приходят новые данные и при рендере я перетираю изначальный books. Как мне правильно обработать эту ситуацию?
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)
  • Вопрос задан
  • 1576 просмотров
Решения вопроса 1
humiliation
@humiliation
Чем больше знаю - тем больше дурак
сохранять предыдущий результат и добавлять к нему приходящий

я создавал в стейте prevData = [];

все приходящие тебе данные prevData.push();

в рендере просто мапишь prevData.map();

получится эффект подгрузки. Если данные просто список с некоторой инфой - до ~300 строк в рилтайме работает неплохо.

пс и не объявляй функции внутри компонентов, как это у тебя в букс сделано.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы