user14578904
user14578904

Reputation:

How to use Infinite Scroll with React Native?

I'm trying to fetch new data everytime the user scrolls to the bottom like this :

<FlatList
    onEndReachedThreshold={0}
    onEndReached={LoadMoreRandomData}
    data={data}
    keyExtractor={(item) => item.email.toString()}
    renderItem={({ item }) => <Text style={{ marginVertical: 100 }}>{item.email}</Text>}
/>

The function that gets called when user gets to the bottom of FlatList:

useEffect(
        () => {
            if (page !== 1) {
                setLoading(true);
                axios
                    .get(`https://randomuser.me/api/?results=10&page=${page}`)
                    .then((res) => {
                        setData((prev) => res.data.results.concat(prev));
                        setLoading(false);
                    })
                    .catch((e) => {
                        setLoading(false);
                    });
            }
        },
        [ page ]
    );

    const LoadMoreRandomData = () => {
        setPage((prev) => prev + 1);
    };

The problem is when useEffect gets called the whole screen disappears for a couple of seconds .

How can I fetch new data and setState with the old data and the screen doesn't flash ?

Upvotes: 1

Views: 703

Answers (2)

Jose Greinch
Jose Greinch

Reputation: 458

you might want to use a useCallback hook there to prevent the function from being re-created as well.

const fetchData = useCallback(() => {
....
}, []);

This will make it more performant as well as having page as an argument

const fetchData = useCallback((page) => {
...
}, []);

Upvotes: 0

Sagar Shakya
Sagar Shakya

Reputation: 654

You should extract the API call from useEffect() to a seperate function. Currently, when page changes, useEffect() is called which rerenders the whole screen.

Try something like this:

useEffect(
    () => {
        fetchData();  
    }, []
);

const fetchData = () => {
 if (page !== 1) {
    setLoading(true);
    axios
        .get(`https://randomuser.me/api/?results=10&page=${page}`)
        .then((res) => {
            setData((prev) => res.data.results.concat(prev));
            setLoading(false);
        })
        .catch((e) => {
            setLoading(false);
        });
    }   
}

const LoadMoreRandomData = () => {
    setPage((prev) => prev + 1);
    fetchData();
};

Upvotes: 1

Related Questions