0

I implement Suspense from React in my app.

I have this code in the Page :

const Articles = React.lazy(() => import("./../components/Articles/Articles"));

...

<Suspense fallback={<ArticlesSkeletons />}>
    <Articles selectedCategories={selectedCategories} />
</Suspense>

And in Articles, I fetch data and display it :

const [articles, setArticles] = useState<Article[] | null>(null);

useEffect(() => {
    // fetch data and store to articles state
}, [articles]);

return (
        articles && (
            <div>
                <div>
                    {articles.map((article, index) => {

                        return (
                            // my structure
                        );
                    })}
                </div>
                )}
            </div>
        )
    );

Problem : I can see the Skeleton displayed, but when it disappear, instead of having the list of articles, it is empty for a second.

  • Page load
  • Skeleton appears
  • No articles displayed for a second
  • All articles displayed.

Why do I have no articles for a second ? It should display skelton as long as data are not loaded

Johan
  • 2,088
  • 2
  • 9
  • 37

1 Answers1

1

You are not rendering the skeleton while the articles are being fetched.

Try this:

const [articles, setArticles] = useState<Article[] | null>(null);

useEffect(() => {
    // fetch data and store to articles state
}, [articles]);

return (
    articles ? (
        <div>
            <div>
                {articles.map((article, index) => {

                    return (
                        // my structure
                    );
                })}
            </div>
            )}
        </div>
    ) : <ArticlesSkeletons />
);

conditionally render articles if there are articles otherwise render the skeleton.

Note that you should also handle error cases. Furthermore, is suspense really needed? Usage of suspense in a client side rendered app is usually for code splitting (reducing initial bundle size). This appears to be a very light component, using suspense is probably unnecessary.

Asplund
  • 2,254
  • 1
  • 8
  • 19
  • I thought about this but it makes no sense to call the skeleton in fallback of Suspense and call it again in Articles. How can I render the skeleton while they are fetched without using a loading state or the conditinally rendered articles ? – Johan Mar 06 '23 at 10:35
  • 1
    You should probably use a fetching library such as [react query](https://react-query-v3.tanstack.com/) this will handle the state of your fetch state for you. It will also handle caching, retries etc. – Asplund Mar 06 '23 at 10:37