reactjsloadingreact-suspense

Empty data displayed before data is loaded - React Suspense


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.

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


Solution

  • 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.