-
Notifications
You must be signed in to change notification settings - Fork 434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Possible evolution of the Relay integration with Next.js #269
Conversation
Also, worth noting: this version publish of the same query payload 3 times (maybe more): two times on the server, for SC and under each RelayRoot. And then on the client, under RelayClientRoot. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Haven't tested locally yet, but the user-facing apis look nice, and are definitely more in line with what a server components implementation could do. Was attempting something like this myself but got stuck not knowing the relay apis well enough to piece it all together.
I looked at the code and found a few nitpicks and questions. But will take another look again after running the code.
const environment = useMemo(() => { | ||
const environment = createEnvironment(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little confusing imo that these are named the same thing.
export default function RelayClientRoot(props: { | ||
children: React.ReactNode; | ||
fetchedQueries: readonly FetchRecord[]; | ||
}): React.ReactElement { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the return type here help in any way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, it just a muscle-memory from working with flow (where every public export has to be explicitly typed - args/return type).
function createFetchRecord( | ||
operationDescriptor: OperationDescriptor, | ||
response: GraphQLSingularResponse | ||
): FetchRecord { | ||
return { | ||
operationDescriptor, | ||
response, | ||
} as FetchRecord; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why have this as a function? It looks like it only takes two inputs and puts them in an object. If you just add them as an object to the fetchRecords: FetchRecord[]
directly you'd get the same kind of type errors (if that is the goal).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to simplify this part. Initial version were exposed this type to the user (and I was trying to make it opaque). We don't need this now, I think
<div className={styles.main}> | ||
<MainViewClientComponent preloadedQuery={preloadedQuery} /> | ||
</div> | ||
<Suspense fallback="Loading..."> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should likely be a loading.tsx
instead since that will show up earlier than the suspense fallback for pages.
https://beta.nextjs.org/docs/routing/loading-ui. The "Good to know" section:
"Navigation is immediate, even with server-centric routing."
{props.children} | ||
</RelayClientRoot> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's possible to init this in layout.tsx
, but without data, and then have another client component for each page that just adds the queried data "top root" one.
That could allow keeping data around while navigating, but ofc doesn't stop the server components from refetching data that is already there.
Can we find a way to use the same function “useFragment” on both client and server? |
Well, since |
Lächeln
Am 11. Jan. 2023, 13:41 +0100 schrieb Andrey Lunyov ***@***.***>:
… > Can we find a way to use the same function “useFragment” on both client and server?
Well, since readFragmentData this is not part of the core framework, you can name it useFragment, but for the sake of example, and to be explicit (and avoid possible confusion) I named it differently.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Ugh... Accidentally pushed this to the main branch. Already reverted, I'll resubmit PR. |
Re-opened as #270 |
Note: This is WIP and not ready to be merged. I’m sharing for feedback and adjustments on the direction.
Summary:
Data-fetching for routes is happening in the Relay Server Components, using
fetchQuery
this version is different from what we export fromrelay-runtime
- (maybe we’ll need a different name). Internally, it fetches the query, publish to the relay store. ThisfetchQuery
can only be called on the server.RelayRoot
- RSC, simple wrapper, that passes serialized list of fetched queries to theRelayClientRoot
RelayClientRoot
- client component that wraps the children with Relay context provided, and publishes the fetched server queries to the client store, so the state of the local store is matching the one on the server.RelayClientRoot
is normal client-first relay with hooks and things... But there is no root query component (withusePreloadedQuery
or similar...)Instead of
useFragment
on the server we can usereadFragmentData
function - this will allow for individual server components define own data requirements, and the view will be fully server-rendered, with possible client leafs. The fragments composed into a query and fetched in the top RSC withfetchQuery
.So, this is a “sketch” of the possible integration, so many things may not work:
RelayClientRoot
Not sure if it’s working:
useLazyLoadQuery
- underRelayClientRoot.