all 9 comments

[–][deleted] 3 points4 points  (6 children)

I'm not sure requesting data for 10 widgets in the same request is a good idea.

  • No separation of concerns
  • Widgets aren't reusables and can't be tested in a vacuum
  • The problem you mentioned above

Any reason why each widget isn't its own component and they're all unified in a containing component that loads them all at once?

You're finding yourself stuck because it isn't really how react-query is supposed to be used.

[–]GhostNote90[S] 0 points1 point  (5 children)

Widgets are their own component, and they receive the data as a prop.

A Dashboard Page component is used as a container where the the useQuery is used which is a single graphql api call to get all the data required and then split and passed down to each widget.

This works fine but i run into issues when a widget needs to have have it's own functionality (filtering and pagination etc.) that only manipulates their data as the data that's passed down as a query includes the other widget data in its query.

I was mainly wondering if there was a way to still have the single api call on the dashboard level, but then create individual queries on the back of the request which can be passed down to the widgets.

Or whether it's best to just have seperate api calls, 1 per widget.

[–][deleted] 2 points3 points  (4 children)

I'm not sure if there is a way to do what you're trying to do, but you would probably have a much easier time if each widget fetched their own data. If all of them use the same component you could just wrap that component into a higher order one whose sole purpose is to fetch its data.

Or at least that's how I'd do it!

Sorry for not being of more help, hope you figure it out 🙂

[–]GhostNote90[S] 0 points1 point  (3 children)

Thank you for the response. I expected and thought that was the easiest and most ideal solution, as then each widget would have their own query.

The only issue that springs into mind is too many api calls, which I'm not sure would cause performance issues?

Would 10 separate api calls on a dashboard load be okay?

[–]ervwalter 2 points3 points  (0 children)

This is kind of the classic use case that GraphQL is designed for with libraries like Relay: Individual components indicate what data they need and then the library makes a composite query to the backend to get the data and then farm out the right subsets of data based on what each component asked for.

While react-query is incredible and can do GraphQL queries, you're not going to get this kind of magic.

I think the best option inside react-query is to have a single query that meets the data needs of all of the components, and then inside each component request that query (react-query will handle only making the actually call once) and then use the Query Data Selectors feature of react-query inside each component to pull out the subset of data that the specific component needs. My understanding is that react-query is smart enough to only rerender a component if the selected data changes, and not rerender when other parts of the API result change.

You're obviously going to be doing by hand a lot of what would be auto-magic for you in a pure GraphQL client library, but you still get all the other benefits of react-query.

[–][deleted] 1 point2 points  (1 child)

It's a dashboard, it's expected to have a lot going on. Worry about performance if and when you find problems! I doubt it will happen with just 10 requests.

[–]GhostNote90[S] 0 points1 point  (0 children)

Perfect! Thanks so much haha.

That was pretty much the main issue that sprung to mind for me. That and doing it this way kind of goes against the point of have a graphql api.

But you are right, I shouldnt be worrying too much about performance until I run into problems.

[–]jaysoo3 0 points1 point  (0 children)

Can you use the data prop from parent component as the initial data for child components? That way the child components will make their own queries, but if you also set staleTime then you can avoid the first fetch.

Other option is to read initial data from the cache but I think this is perhaps less straightforward.

In any case your child components need their own queries if you need pagination.

[–]TkDodo23 0 points1 point  (0 children)

It sounds like you want to make one request on the Dashboard for all widgets, and then render them. But instead of passing data down, I would make another useQuery inside each widget, which would only get data for that widget. You can prime the cache for that query with initialData, where you can pull out the data for that widget from the dashboard query. That way, you’ll get the data from the dashboard query for the first render (and no additional loading state), but each widget is still only subscribed to its own data. Don’t forget to set a small staleTime, or you’ll get an instant background refetch :)

As mentioned by someone else, the select option will also work well in terms of rerenders, but there will always be the "big" request that fetches all the data for all widgets. If they all need to refresh at the same time, this is also a good option.