Open Togrias opened 4 years ago
I've struggled with this in every version of Relay, but I think experimental
Relay would have you "render-as-you-fetch" with preloadQuery
/usePreloadedQuery
, as demonstrated in this sandbox, where preloadQuery
is setResource(fetchTranslation(value))
and usePreloadedQuery
is resource.read()
. Since fetching happens during state initialization and then callbacks, you can set the state to null (when you don't want a query (like when an input is empty). I appreciate this pattern a lot, but have found it introduces some issues of its own. Any insights would be much appreciated!
@dminkovsky following your example, calling usePreloadedQuery where preloadedQuery is null would throw an error.
My main issue is that hooks can't be skipped during render. So even if you know that preloadedQuery
is null
, you can't skip calling usePreloadedQuery()
.
Compare to the old <QueryRenderer/>
component, where one can pass query={shouldSkip? undefined : graphql...}
as a prop to "disable" it.
@Togrias as I implemented it, usePreloadedQuery()
lives in its own component, and that component is conditionally rendered based on whether preloadQuery
is null
. The suspense boundary is then around the component that contains usePreloadedQuery()
. Something like:
{preloadQuery && <Suspense><Component preloadQuery={preloadQuery} /></Suspense>}
where
const Component = ({preloadQuery}) => {
const result = usePreloadedQuery(/*preloadQuery and other args*/)
// ... render
}
If a query is loading and is not ready, it'll suspend. If there's nothing to load, nothing will render.
Yes, I'm using a workaround like your method too but I think it's like a step backwards since the current QueryRenderer
allows optional queries. Also, conditionally rendering elements may force unwanted mounting/unmounting while switching "modes". Hence my suggestion.
How do you skip queries using QueryRenderer?
<QueryRenderer query={skip? undefined : graphql...
} .../>
@Togrias yeah there's things I don't like about it, too. I just like the "render-as-you-fetch" concept, starting the request in the callback, and passing a "resource" that represents that fetch up into state, to render when ready. And it offers a way to fetch optionally.
That said, I've never understood why optional fetching has never been an explicitly accounted-for use-case. Made me wonder how other people handle it, because it seems to come up all the time for me (eg. empty input).
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Are there any new solution or workaround on this issue?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
For anyone still struggling with this, I've created a package that makes it easier to optionally render relay components. It is just a higher-order component that will wrap your Relay consumers so you can pass in a possibly-null queryRef
to the wrapper and it will only render the child if it's defined. There are some examples in the repo. It's still a little rough so any feedback is appreciated.
I'm not sure if this is 'supported/intended' behaviour, but QueryRenderer allows you to pass an undefined query prop. If no query prop is supplied, then no data is fetched.
This is useful for some components which only need to fetch data under certain circumstances.
The new experimental hooks have no way of omitting the first argument.
I suggest introducing optional varieties of the use LazyLoad / Preloaded Queries that allow the conditional fetching of data.