0

The usePaginator is intended to fetch data (and set hasNextPage if there is more data to fetch), once page, userData or category change, but it causes infinite loop allegedly due to setInfo which appears in method which then is called in useEffect hook. UI gets unresponsive, though there is an array of dependencies, the question is how to solve this problem? I am looking for your responses, Guys

ScrollableList.js

import React, { useRef, useContext, useEffect, useState } from 'react'
import { UserDataContext } from '../../utils/contexts'
import Followers from './Followers'
import Following from './Following'
import IncomingReqs from './IncomingReqs'
import SentReqs from './SentReqs'
import usePaginator from '../../hooks/Profile/usePagination'


export default ({ category, userId }) => {
  const UserData = _ => useContext(UserDataContext)

  const [ page, setPage ] = useState(1)
  const [ loading, setLoading ] = useState(false)

  const userData = useRef(UserData())

  const [ hasNextPage, setHasNextPage, info ] = usePaginator(category, {
    'Followers' : UserData().followers,
    'Following' : UserData().following,
    'Sent Requests' : UserData().requestsTo !== undefined ? UserData().requestsTo : null,
    'Incoming Requests' : UserData().requestsFrom !== undefined ? UserData().requestsFrom : null
  }, userId, page, val => setPage(val), val => setLoading(val))

  useEffect(_ => {
    document.getElementById('scrollableList').addEventListener('scroll', definePosition)
    return _ => document.getElementById('scrollableList').removeEventListener('scroll', definePosition)
  })

  const definePosition = e => {
    if(e.target.scrollHeight === Math.floor(e.target.offsetHeight + e.target.scrollTop + 1) && hasNextPage){
      setPage(page + 1)
      setHasNextPage(false)
    }
  }

  return(
    <div id="scrollableList">
      { category === 'Followers' && <Followers followersCount={userData.current.followers} data={info}/> }
      { category === 'Following' && <Following followingCount={userData.current.following} data={info}/> }
      { category === 'Incoming Requests' && <IncomingReqs incomingReqCount={userData.current.requestsFrom} data={info}/> }
      { category === 'Sent Requests'  && <SentReqs sentReqCount={userData.current.requestsTo} data={info}/> }
    </div>
  )
}

usePagination.js

import { useState, useEffect } from 'react'
import fetchRequests from '../../api/profile/stats/fetch-requests'
//import fetchFollowers from '../../api/profile/stats/fetch-followers-following'


export default (category, userData, userId, page, setPage) => {
  const [ hasNextPage, setHasNextPage ] = useState(false)
  const [ _userData, setUserData ] = useState(userData)
  const [ info, setInfo ] = useState([])

  useEffect(_ => {
    setUserData(userData)
  }, [ userData ])

  useEffect(_ => {
    setPage(1)
    if(_userData[ category ] > 100) setHasNextPage(true)
    // eslint-disable-next-line
  }, [ category ])

  const loadInfo = _ => {
    if(userData[category] > 0){
      if(category === 'Sent Requests'){
        return fetchRequests(page, false)
          .then(res => {
            setInfo([...info, ...res])
            if(info.length + res.length < userData[category])
              setHasNextPage(true)
          })
      }
    }
  }

  useEffect(_ => {
    loadInfo()
  }, [ page, userData, category ])

  return [ hasNextPage, setHasNextPage, info ]
}

SentReqs.js

import React from 'react'


export default ({ sentReqCount, data }) => {
  return(
    <>
      { sentReqCount === 0 && <p>You have not sent any requests yet, when you will, you will see them here</p> }
    </>
  )
}
  • Not the cause of issue, but what is `const UserData = _ => useContext(UserDataContext)`? `useContext` hook should be in function body. – Drew Reese Nov 02 '20 at 19:08
  • 1
    In the ScrollableList.js the useEffect for scroll listener does not have a dependency array. You should set it. Move the definition of `definePosition` inside the useEffect – Julian Kleine Nov 02 '20 at 19:13
  • 1
    Move the function body of `loadInfo` directly into the useEffect. Remove `_userData` and only use `userData`, can't see an advantage of the local state. Remove the eslint disable and fix the deps array – Julian Kleine Nov 02 '20 at 19:15

0 Answers0