10

I'm using the react-infinite-scroll-component to implement the infinite scroll component. The configuration of the component is:

<div id="scrollableDiv" style={{ height: 300, overflow: "auto" }}>
       <InfiniteScroll
         dataLength={texts.length}
         next={getText}
         hasMore={true}
         loader={<h5>Loading...</h5>}
         endMessage={<p style={{textAlign:'center'}}><b>Yay! You've seen it all!</b></p>}
         scrollableTarget="scrollableDiv"
         >
         {<Texts texts = {texts}/>}
         </InfiniteScroll>
</div>

where texts is simply a state array of some text objects; const [texts, setTexts] = useState([])
This is the getText method to be called in next :

const getText = async ()=>{

        const res = await axios.get("http://localhost:3001/api/sth",{
            params: {
                ids: followings.map(i => i.id),
                str_ids: followings.map(i => i.str_id)
              },
              paramsSerializer: params => {
                return qs.stringify(params)
              }
        });

        let str_ids_res = res.data.map(i => i.string_id)
        let texts_res = res.data.map(i => i.texts)
        console.log(texts_res)

        const filtered_res = //some processing here on texts_res
        /* eslint eqeqeq: 0 */
        if(!arrayIsEqual(filtered_res,texts)){
            console.log("Not equal")
            // append arrays to a array state
            setTexts((prevtexts) => prevtexts.concat([...filtered_res]))
        }

    }

await axios.get("http://localhost:3001/api/sth")

always return two different texts from DB so setTexts should always get called.

component is a card component from semantic UI tho.

const Texts = ({texts}) =>{
    return (
        <>
            {texts.map(text =>(
                <div key={text.id}>
                    <Card>
                        <Card.Content>
                            <Card.Description>
                            {text.full_text}
                            </Card.Description>
                        </Card.Content>
                    </Card>
                </div>
            ))}
        </>
    );
}

InfiniteScroll component only fires Next once even though my datalength variable is setting correctly.
PS. the texts is empty initially so when I start the app, only 'Loading....' is called

3 Answers 3

21

After some experiments, passing height = {some height} as props to InfiniteScroll does the trick..

<div id="scrollableDiv" style={{ height: 300, overflow: "auto" }}>
                                    <InfiniteScroll
                                    dataLength={tweets.length}
                                    next={handleScrolling}
                                    hasMore={!isEnd}
                                    loader={<h5>Loading...</h5>}
                                    scrollThreshold={1}
                                    height={300}
                                    endMessage={
                                        <p style={{textAlign:'center'}}><b>Yay! You've seen it all!</b></p>
                                    }
                                    scrollableTarget="scrollableDiv"
                                    >
                                    {<Tweets tweets = {tweets}/>}
                                    </InfiniteScroll>
</div>
Sign up to request clarification or add additional context in comments.

Comments

1

Please do not initialize 'texts' with an empty array, you must initialize the 'texts' array with some array of objects (for example 10 or 20).

In the initial render of your code (at the first time). you can just fire an API in

useEffect(()=>{
  // make API call which your firing in the next call function
},[])

So your component gets initialization then after it will start behaving as expected.

For your understanding, Please refer to the sample example in "code sandbox" https://codesandbox.io/s/elated-danny-k4hylp?file=/src/index.js

Comments

1

I encountered the same issue, and here’s a trick that worked for me:

I added an external component (or a dummy div) into the at top or bottom to help trigger the next function. Here’s an example:

  <InfiniteScroll
  {...props}
>
  <div style={{ height: 20 }}></div> {/* External component to adjust the scroll */}
</InfiniteScroll>

1 Comment

^ more than 12 and i dunno why @@"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.