how to use this feature with React Suspense on the server side?
videni opened this issue · 6 comments
const App = () => {
return (
<RelayEnvironmentProvider environment={environment} >
<Suspense fallback={<PageLoding/>}>
<Layout>
<Component {...pageProps} />
</Layout>
</Suspense>
</RelayEnvironmentProvider>
);
}
try {
const element = <App />
await ssrPrepass(element);
return render(renderElementToString, element);
}
catch (err) {
}
I did something as the abive, still get the two errors
rror: ReactDOMServer does not yet support Suspense.
at ReactDOMServerRenderer.render (/Users/vidy/www/acme-admin-ui1/node_modules/react-dom/cjs/react-dom-server.node.development.js:3735:25)
at ReactDOMServerRenderer.read (/Users/vidy/www/acme-admin-ui1/node_modules/react-dom/cjs/react-dom-server.node.development.js:3536:29)
at renderToString (/Users/vidy/www/acme-admin-ui1/node_modules/react-dom/cjs/react-dom-server.node.development.js:4245:27)
at render (/Users/vidy/www/acme-admin-ui1/node_modules/next/dist/next-server/server/render.js:81:16)
at Object.renderPage (/Users/vidy/www/acme-admin-ui1/node_modules/next/dist/next-server/server/render.js:300:24)
[ event ] client pings, but there's no entry for page: /_error
Warning: Relay: Tried reading fragment `BasicLayoutQuery` declared in `useLazyLoadQuery()`, but it has missing data and its parent query `BasicLayoutQuery` is not being fetched.
This might be fixed by by re-running the Relay Compiler. Otherwise, make sure of the following:
* You are correctly fetching `BasicLayoutQuery` if you are using a "store-only" `fetchPolicy`.
* Other queries aren't accidentally fetching and overwriting the data for this fragment.
* Any related mutations or subscriptions are fetching all of the data for this fragment.
* Any related store updaters aren't accidentally deleting data for this fragment.
Warning: Relay: Expected to have been able to read non-null data for fragment `BasicLayoutQuery` declared in `useLazyLoadQuery()`, since fragment reference was non-null. Make sure that that `useLazyLoadQuery()`'s parent isn't holding on to and/or passing a fragment reference for data that has been deleted.
Hiya, sorry for the late reply! 👋
This is a discrepancy on react-dom/server
. It basically doesn't allow use of the Suspense
element on the server-side, especially since it's a noop. In react-ssr-prepass
the Suspense
element doesn't have any functionality and is a noop. Only thrown suspense promises themselves are being processed, but those don't interact with Suspense
.
So the right thing to do is to not use Suspense
on the server-side, possibly by simply checking typeof window
and leaving it out.
So the right thing to do is to not use Suspense on the server-side, possibly by simply checking typeof window and leaving it out.
In place of the regular <Suspense />
component, I am using <SsrCompatibleSuspense />
where const SsrCompatibleSuspense = process.browser ? Suspense : props => props.children
.
The only problem with this is that React will log some warnings when rehydrating browser-side after SSR, since what's rendered on the browser is supposed to match what was rendered on the server.
Warning: Did not expect server HTML to contain a
in .
in main (at App.js:24)
in Unknown (at ssr.js:10)
in IndexPage (at gqless.js:60)
in withGqless(IndexPage) (created by App)
in App
in Container (created by AppContainer)
in AppContainer
The above warning is actually wrong about the specifics. The html tree is the exact same on server & browser; only the React element tree is different.
But are these warnings in any way valid?
@kitten Any chance we can reopen this?
I recognize that this is not an issue with this package, but an issue sorta goes with this package. This package solves one part of the problem (using React Suspense APIs in components that will be SSRd), and this issue is the second part of that problem.
@zenflow This should (or rather used to?) actually work since React introduced an exception to their SSR mismatch checks that accepted an added Suspense
boundary on the client-side. I'm not sure whether that was possibly rolled back: facebook/react#16943
Edit: I can't really find the affected code in the React codebase anymore. So this behaviour may have changed in a minor release. I'm wondering whether this change has moved over to the new createRoot
APIs and this is a non-issue there.
Further, I don't think we can reopen this since it's not actionable. There's nothing we can do about this warning if React decided to re-add it unfortunately.
So the right thing to do is to not use Suspense on the server-side, possibly by simply checking typeof window and leaving it out.
In place of the regular
<Suspense />
component, I am using<SsrCompatibleSuspense />
whereconst SsrCompatibleSuspense = process.browser ? Suspense : props => props.children
.The only problem with this is that React will log some warnings when rehydrating browser-side after SSR, since what's rendered on the browser is supposed to match what was rendered on the server.
Warning: Did not expect server HTML to contain a in .
in main (at App.js:24)
in Unknown (at ssr.js:10)
in IndexPage (at gqless.js:60)
in withGqless(IndexPage) (created by App)
in App
in Container (created by AppContainer)
in AppContainerThe above warning is actually wrong about the specifics. The html tree is the exact same on server & browser; only the React element tree is different.
But are these warnings in any way valid?
@kitten Any chance we can reopen this?
@zenflow Did you ever find a workaround for this issue?
@jesster2k10 My workaround in the end was to ignore the warnings. I don't believe they are actually valid, because of the reasoning above: "The html tree is the exact same on server & browser; only the React element tree is different." If the html tree actually differed from server to browser (as the warning implies) then we would have a problem, but I don't see the problem with the React element tree differing.