0
export default function TableBooks(props) {

const reducer = (state, action) => {
switch (action.type){
  case "start":
  return { ...state, loading: true }


  case "loader":
      initial.after = initial.after+ action.newData.length
      return { ...state, loading: false, data: [...state.data, ...action.newData],
      more: action.newData.length === 10,
      after: initial.after
      }


  default:
  throw new Error('Don know')
   }
   }
  const [state, dispatch] = React.useReducer(reducer,  {
  loading: false,
  more: true,
  data: [],
  after: 0
 })
   const {loading,more,data,after} = state;
   const handleScroll = () => {
   const scrollTop = document.documentElement.scrollTop
   const clientHeight = document.documentElement.clientHeight 
   const scrollHeight  = document.documentElement.scrollHeight;

   if ( scrollHeight - scrollTop === clientHeight) {

    dispatch({type: 'start'})
    const newData = rows.slice(initial.after, initial.after+10)
    console.log(newData)
    dispatch({type: 'loader',newData});
    }
    }
    React.useEffect(() => {
    window.addEventListener('scroll', handleScroll);

    }, [])



                           
                         const rows = props.data
              if (rows === null || rows === undefined){
            return 'loading...'
             }
            else{
            return (

                 <div>
                 <div style={{display: 'block'}}>
                 <Chip  label="Basic" variant="outlined" />
                 <Chip  >Title</Chip>
 
                  </div>
                 <TableContainer component={Paper}>
                <Table className={classes.table} aria-label="customized table">
              
            <TableBody>
            {data.map((row,i) => (
                 <StyledTableRow>  
                  <StyledTableCell align="right">{row.userId}</StyledTableCell>
                     <StyledTableCell align="right">{row.title}</StyledTableCell>
      
                   <StyledTableCell align="right">{row.body}</StyledTableCell>
                   <StyledTableCell align="right"><button onClick= 
                   {()=>handleCart(i)}>Add</button></StyledTableCell>

                 </StyledTableRow>
                   ))}
                {loading && <div>Loading...</div>}
               {!loading && (
               <div style={{background: 'green'}}>
                <button onClick={() => {
                dispatch({type: 'start'})
                 const newData = rows.slice(after, after+10)
                dispatch({type: 'loader',newData});
                }}>Load More</button>
               </div>
                )}

              </TableBody>
              </Table>
              </TableContainer>
              </div>
              );
                }

                }

I am trying to implement Lazy load on the react table where data is fetched from api.

I want the feature that when user scrolls to bottom the new set of data is inserted to the table. So I used react useReducer hook so when user scrolls to end hook gets triggered(HandleScroll function). The problem is sometime I am getting the result. While sometime the data is not added. On debugging i found that newData array is empty sometimes in below code.

if ( scrollHeight - scrollTop === clientHeight) {

  dispatch({type: 'start'})
  const newData = rows.slice(initial.after, initial.after+10)
  console.log(newData)
  dispatch({type: 'loader',newData});
  } 

Can anyone help me what should I do so every time I get the desired result Thank You

Pratyush Narain
  • 381
  • 2
  • 9

2 Answers2

0

Quick suggestion.

Please check if (scrollHeight - scrollTop === clientHeight) {

shouldn't be > or < comparison operator here?

rajakvk
  • 9,775
  • 17
  • 46
  • 49
  • Not working. There is no problem in logic Sometimes it is working while sometime it is not. After debugging I found out when the handlescroll event triggers the newData array does not populate (While sometimes it does) and the empty newData array is given to ' dispatch({type: 'loader',newData});'. Can you help me plz – Pratyush Narain Feb 14 '21 at 14:57
0
 React.useEffect(() => {
    window.addEventListener('scroll', handleScroll);

    }, [])

you didn't add handleScroll as dependencies in useEffect hook

you can also add useCallback for handleScroll

const handleScroll = React.useCallback(()=>{
...type code here
},[]) // add dependencies here also like rows etc. values that will change

React.useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return function cleanup(){
        window.removeEventListener("scroll",handleScroll)
    }
 }, [handleScroll])

and reducer function where initial veriable come from??

initial.after = initial.after+ action.newData.length