flowforfrank / webtips

https://webtips.dev
1 stars 0 forks source link

how-to-improve-data-fetching-in-react-with-suspense #6

Open utterances-bot opened 2 years ago

utterances-bot commented 2 years ago

How to Improve Data Fetching in React With Suspense? - Weekly Webtips

The Suspense component in React is a new feature that makes data fetching a breeze. It lets you avoid introducing unnecessary logic to your components...

http://localhost:1234/how-to-improve-data-fetching-in-react-with-suspense

flowforfrank commented 2 years ago

Dávid Vendel • 2 months ago Thank you for great article. How would you do it if you had an API that can give you only one todo, based on paramter? And you'd want to list several todos on a one page, each wrapped in Suspense? My issue is i'm unable to give parameter to getTodos, as it's a function outside of component...

flowforfrank commented 2 years ago

Dávid Vendel • 2 months ago Thank you for great article. How would you do it if you had an API that can give you only one todo, based on paramter? And you'd want to list several todos on a one page, each wrapped in Suspense? My issue is i'm unable to give parameter to getTodos, as it's a function outside of component...

Hey Dávid! Thank you for your feedback.

If I understand correctly, you want to list several todos on a single page, but the API gives you back only one todo item? (presumably based on an id)

If this is the case, my suggestion would be to solve this on the API level. It needs to provide you with the list of data in an array, with each object populated with the necessary data. That way, you still end up using a single Suspense, and you also keep the number of network requests to a minimum.

In case this cannot be solved on the API level for whatever reason, I suggest using Promise.all to fetch each node individually that is needed, and once all of the requests are fulfilled, you can return a single array, and you end up with one Suspense again.

I would advise keeping the number of Suspenses to the minimum.

flowforfrank commented 2 years ago

Dávid Vendel • 2 months ago Thank you for great article. How would you do it if you had an API that can give you only one todo, based on paramter? And you'd want to list several todos on a one page, each wrapped in Suspense? My issue is i'm unable to give parameter to getTodos, as it's a function outside of component...

Hey Dávid! Thank you for your feedback.

If I understand correctly, you want to list several todos on a single page, but the API gives you back only one todo item? (presumably based on an id)

If this is the case, my suggestion would be to solve this on the API level. It needs to provide you with the list of data in an array, with each object populated with the necessary data. That way, you still end up using a single Suspense, and you also keep the number of network requests to a minimum.

In case this cannot be solved on the API level for whatever reason, I suggest using Promise.all to fetch each node individually that is needed, and once all of the requests are fulfilled, you can return a single array, and you end up with one Suspense again.

I would advise keeping the number of Suspenses to the minimum.

Dávid Vendel ↩️ Ferenc Almasi • 2 months ago

Hello, Yes, I want to do that and don't want to change API. Imagine there is facebook profile API that has 2 billion profiles. I would want to render 10 of them on my site (pure fiction). I wouldn't want to be changing API.. I would want to create one component that is rendering one profile at at time, have it inside Suspense, and then render them all by mapping through an array of user ids. I would want each of the profile to be rendered immediately when I get response from API. I imagine Suspense is build just for that. I understand the promise.All approach, but that sounds sub-optimal to me.

I really just want to be able to call for these data parametrically. You are doing const todoList = todos(); Is it possible to put parameter in this todos() function, which would then get transferred to getTodos and to fetch? So fetch api call would be parametrised & I would have const todoList depend of what userId is this Component rendering. This would normally work, but it seems my problem is that these functions are outside of components so I can't make it work.

Inspired by you I made a simple CodeSandbox where I fetch all data at once, now I'd like to fetch them one by one (Api accepts &id=Number as parameter)

flowforfrank commented 2 years ago

Dávid Vendel • 2 months ago Thank you for great article. How would you do it if you had an API that can give you only one todo, based on paramter? And you'd want to list several todos on a one page, each wrapped in Suspense? My issue is i'm unable to give parameter to getTodos, as it's a function outside of component...

Hey Dávid! Thank you for your feedback. If I understand correctly, you want to list several todos on a single page, but the API gives you back only one todo item? (presumably based on an id) If this is the case, my suggestion would be to solve this on the API level. It needs to provide you with the list of data in an array, with each object populated with the necessary data. That way, you still end up using a single Suspense, and you also keep the number of network requests to a minimum. In case this cannot be solved on the API level for whatever reason, I suggest using Promise.all to fetch each node individually that is needed, and once all of the requests are fulfilled, you can return a single array, and you end up with one Suspense again. I would advise keeping the number of Suspenses to the minimum.

Dávid Vendel ↩️ Ferenc Almasi • 2 months ago

Hello, Yes, I want to do that and don't want to change API. Imagine there is facebook profile API that has 2 billion profiles. I would want to render 10 of them on my site (pure fiction). I wouldn't want to be changing API.. I would want to create one component that is rendering one profile at at time, have it inside Suspense, and then render them all by mapping through an array of user ids. I would want each of the profile to be rendered immediately when I get response from API. I imagine Suspense is build just for that. I understand the promise.All approach, but that sounds sub-optimal to me.

I really just want to be able to call for these data parametrically. You are doing const todoList = todos(); Is it possible to put parameter in this todos() function, which would then get transferred to getTodos and to fetch? So fetch api call would be parametrised & I would have const todoList depend of what userId is this Component rendering. This would normally work, but it seems my problem is that these functions are outside of components so I can't make it work.

Inspired by you I made a simple CodeSandbox where I fetch all data at once, now I'd like to fetch them one by one (Api accepts &id=Number as parameter)

That is possible too, you just need to pass down the ID to the API. In order to do that, you will have to rework a couple of things, however. I've created a fork from your CodeSandbox, where you can see the code in one piece.

The important part is inside Api.js. In UserProfile when you call the resource, you want to pass it an id. Since this resource is returning a function, you need to pass this id to the returned function on line:22 inside Api.js. Since you also need to pass it down to the suspender, you need to turn it into a function that returns the promise at the end. That way, you can pass the ID all the way down to the fetch request programmatically.

Let me know if you need more clarification on anything.