Open dwwoelfel opened 4 years ago
Test
@dwwoelfel
why is useMemo
used here instead of useEffect
?
also instead of
React.useMemo(() => {
if (initialRecords) {
environment.getStore().publish(new RecordSource(initialRecords));
}
}, [initialRecords]);
i am using
React.useMemo(() => {
const operation = createOperationDescriptor(query.default, {
issueNumber: issueNumber
})
RelayEnvironment.commitPayload(operation, props.records)
}, [props])
is there a performance difference between commitPayload
& environment.getStore().publish()
seems like with publish i am calling the network more frequently
This article is really a GitHub issue that was fetched by Relay through OneGraph and turned into an article by Next.js
It uses
getStaticProps
to deliver a statically-generated version of the article. That way search engines and people with javascript disabled can see the content.There may be new comments or reactions since the last time Next.js ran
getStaticProps
, so React hydrates the page on the client and we re-render with the latest version of the data fetched from OneGraph.Our
getStaticProps
function runs the query for the article and serializes the Relay environment to JSON, which is what gets used to statically render the page.Then we put the initialRecords into the environment when we hydrate the page on the client.
The
'store-and-network'
fetchPolicy
tells Relay to render with data from the store initially, then send off a network request to get the latest data.Relay won’t tell you if the data that you’re rendering with is from the network or from the cache. It’s a difficult problem for Relay to solve generally. In many cases, it’s not even clear what it means for data to be cached. Relay has a central store that all queries add data to. It would be difficult and expensive to keep track of the provenance of every piece of data in the store.
For our use-case, the question is more straightforward. Was the data added to the store by publishing our cached
initialRecords
, or through the fetch thatuseLazyLoadQuery
initiated?We can answer that question by leveraging client-only fields and custom handlers.
Client-only fields
Relay allows you to extend your server schema with client-only fields. This is typically used for local state management, and can replace tools like redux depending on the use case.
We’ll add a client-only field to the
GitHubIssue
type by extending the type in a new file calledsrc/clientSchema.graphl
.Then we’ll add the field to our query and specify that it should use a custom handler with the
@__clientField
directiveThe
@__clientField
directive takes ahandle
argument, which is just a string we will use to determine which handler to use.Custom handlers
Handlers are extension points that allow for custom logic to add data to the store. Relay has default handlers built-in to deal with things like
Connection
types, a pattern many GraphQL services use for pagination.We’ll write our own handler for
isClientFetched
and use it when we construct the environment, with a fallback to the default handler:The handler will run when a fetch, like the one triggered by
useLazyLoadQuery
, adds data to the store, but not when we add records directly to the store withstore.publish
.On the server, the
isClientFetched
field will be set to false. It will only become true when we fetch the query on the client.The full code for this is in the OneBlog repo. We use
isClientFetched
on OneBlog to determine if we should show a welcome page to the author before they have published any articles.You can deploy your own blog backed by GitHub issues on Vercel.