25

I'm trying to lazy load a list of data with suspense and dynamic import in Nextjs. But getting following error:

Error: This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition.

I've tried using startTransition() but couldn't understand how to use it.

DataList.tsx:

import React, { useState } from "react";

interface Props {
  data: any[];
}

const DataList = ({ data }: Props) => {
  return (
    <div>
      {data &&
        data.map((item) => {
          return (
            <div key={item._id}> 
              {item.title} 
            </div>
          );
        })}
    </div>
  );
};
export default DataList;

DataPage.tsx

import React, { Suspense, useEffect, useState } from "react";
import dynamic from "next/dynamic";
const DataList = dynamic(() => import("./DataList"), {
  suspense: true,
});

interface Props {}

const Projects = ({}: Props) => {

  const [data,setData] = useState<any[]>();

  useEffect( () => { 
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(json => setData(json))
  } , []) 

  return (
    <>
      <Suspense fallback={<p>LOADING</p>}>
        <DataList data={data} />
      </Suspense>
    </>
  );
};


export default DataPage;
Hashem Mashem
  • 317
  • 1
  • 5
  • 11
  • Can you post the definition of `ProjectsList`? – baig Jun 07 '22 at 20:35
  • Your code example is not even using `DataList` which is supposed to be imported dynamically. – baig Jun 07 '22 at 20:41
  • @beig I have fixed it. You can check the code again. – Hashem Mashem Jun 11 '22 at 13:37
  • 1
    This snippet isn't enough to reproduce the problem (I tried, it doesn't cause the error you report). – Maël Nison Jun 12 '22 at 13:01
  • 2
    Did you figure this out? I'm having the same problem – Mel Nov 18 '22 at 22:33
  • 1
    It's probabbly a bug in react you can see this isse here: https://github.com/facebook/react/issues/25625, and PR: https://github.com/facebook/react/pull/25692 – Jalal Dec 05 '22 at 21:31
  • @Jalal This issue is still open it seems, although the PR is merged. Any idea on when this might get live – Aakash Thakur Dec 17 '22 at 12:26
  • try updating your React to the latest it solves the issue. If you are updating a state inside the suspense boundary then use `useTransition()`: https://beta.reactjs.org/apis/react/Suspense#preventing-already-revealed-content-from-hiding – Jalal Dec 17 '22 at 21:33

3 Answers3

0

I guess sometimes this error appears without any possible error.

here is reference: https://www.reddit.com/r/nextjs/comments/yxa87v/im_glad_im_not_the_only_one_that_thinks_this/

Moinul Moin
  • 96
  • 1
  • 6
  • Can you elaborate more? Why adding `ssr:false` will solve the transition issue? – Jalal Dec 26 '22 at 18:59
  • @Jalal ```ssr : false``` is a flag that tells you that you are not importing a component at ```build time( server side import)```, but only for ```client side``` – Mallikarjun M G Jan 29 '23 at 15:10
0

first of all, you are using dynamic import:

In Next.js, the dynamic function is used to dynamically load a component only when it's required, rather than including it in the initial bundle of the application.

And in your case, it seems that DataList Component is a major component in order to render the initial view of the project.

Therefore, in my case removing the Dynamic import solved the issue for me and I am not receiving the Suspense error anymore

Thus, changing the import to be as the below should solve your problem:

import DataList from './DataList';

Here are some examples of where you might want to use dynamic:

1- Large third-party libraries: If you're using a large third-party library in your application, it can significantly increase the initial bundle size. You can use dynamic to load only the parts of the library that are required for certain pages or user interactions.

2- Conditional components: If you have components that are only required for certain user interactions or pages, you can use dynamic to load them only when they are needed, rather than including them in the initial bundle.

3- Slow loading components: If you have components that take a long time to load or render, you can use dynamic to load them only when they are needed, rather than slowing down the initial page load.

4- Server-side rendering compatibility issues: If you have components that are not compatible with server-side rendering, you can use dynamic with the ssr: false option to exclude them from the server-side rendering process.

5- It's important to note that using dynamic can add extra complexity to your application, so it's best to use it judiciously and only when it provides a significant performance benefit. Additionally, it's important to test your application thoroughly to ensure that dynamically loaded components work as expected, particularly with respect to server-side rendering.

Azzam Michel
  • 573
  • 5
  • 8
0

use startTransition instead of useEffect !

I did this and my problem solved ...

  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/34781840) – Hamza Rashid Aug 05 '23 at 22:28