React component fetch data evertime when component render

Hello Everyone,
I want to know that whenever the component renders it fetches data from the database(in my case it’s firebase) everytime.

const BooksList = () => {
    // fetch data from the firebase
    const { docs } = useFirestore('books');

    return (

        <div className="ml-64 pt-12">

            <Heading text="All Books" />

            <div className="grid gap-4 ml-4 grid-cols-3">

            {docs && docs.map(book => {

                return (

                    <BookCard key={book.id} book={book} />

                )

            })}

            </div>

        </div>

    )

}

When I go to /books, it fetches data from the database and seems empty when the page first load.
I see many websites, it only takes sometimes when I visit a certain route first time after that it don’t take any time to show data.
How I achieve this type of functionality.
Thanks

Are you talking about caching the result, or just making it run one time on mount?

For caching you can look at something like SWR. For on mount you can wrap the call inside a useEffect with an empty dependency array.

I don’t really know useFirestore so I can’t say if there is some specific way it is supposed to be used.

This is my useFirestore file.
I want when component first renders then only it takes time to load and when I visit that route the second time, it doesn’t take any time.


import { firestore } from '../config/fbConfig';

import { useAuth } from '../context/AuthContext';

const useFirestore = (collection) => {

    const [docs, setDocs] = useState([]);

    const [loading, setLoading] = useState(true);

    const {currentUser} = useAuth();

    useEffect(() => {

        let unsubscribe = firestore.collection(collection)

        // .orderBy('createdAt', 'desc')

        .onSnapshot((querySnapshot) => {

          const items = [];

          querySnapshot.forEach((doc) => {

            items.push({...doc.data(), id: doc.id});

          });

          setDocs(items);

          setLoading(false);

        });

        return unsubscribe;

      }, []); // eslint-disable-line react-hooks/exhaustive-deps

  

    return { docs, loading };

}

export default useFirestore;```

Well, that sounds like caching. You can implement your own hook, or use a premade hook like SWR. Just searching for fetch hook will give you a bunch of results. Although if you want it to use Redux or persist using local storage or whatnot you may have to look for more specific implementation examples.

Is there any downside to using SWR?
I am using firebase. Is it work perfectly fine with firebase?

No, it does basically the same thing you’ve written there but for any HTTP request + some extra functionality for caching. I would advise reading the SWR code and understanding it – it’s a tiny little library

Thanks @lasjorg @DanCouper