How to load data for a RootContainer supplied to Router on server side?
sidutta opened this issue · 6 comments
I pass a RootContainer with a Relay.Route supplied to it in the isomorphic-relay-router. This root container contains other RootContainers with different Relay.Routes in the component supplied to it. For a complete server side rendering I would like all the data for the RootContainer supplied to router and RootContainers loaded by the component in the supplied RootContainer to be loaded server side.
I read somewhere in the comments that IsomorphicRelay.Renderer should be used in place of the default Relay.Renderer. I can replace the RootContainers with isomorphic renderers. Will it solve the problem? The renderer needs an environment as argument which is different server and client side. How can I effectively use the same renderer while passing in different environments? The problem is particularly serious on server side. I can't create a global variable. So there should be a way to pass the environment created on renderOnServer.js to the IsomorphicRenderer I use in place of RootContainer. this.context.relay is undefined when passed as environment to the renderer.
Why do you need multiple RootContainer
s/Renderer
s in the first place?
Because I don't fetch data for all components from a single viewer query properly traversing the graph. Rather I directly query node for data req of those components by passing the nodeId in the following way:
'use strict';
import Relay, {
Route,
} from 'react-relay';
export default class xyzRoute extends Route {
static routeParams = {
xyzId : ''
};
static queries = {
viewer: (Component) => Relay.QL`query {
node(id : $xyzId) {
${Component.getFragment('viewer')}
}
}`
};
static routeName = 'xyzRoute';
}
Rather I directly query node for data req of those components by passing the nodeId
But you can do it without multiple RootContainer
s/Renderer
s.
Even then, if say I use
<Route path="/" component={HomeScreen} queries={ViewerQueries} prepareParams={(params) => {return {...params}}} >
data is rendered on server. However, if I use
<Route path="/" component={HomeScreenContainer} prepareParams={(params) => {return {...params}}} >
and pass a Route equivalent of ViewerQueries
to the container, data is fetched from the client.
So, are you trying to suggest that I should not use containers/ renderers at all apart from one call to IsomorphicRelay.Rederer
made in renderOnServer.js
?
The reason I use the current pattern is because I dont have to care about the entire graph and keep track of properly calling getFragment amongst parent and children components. I get the flexibility to load containers on demand in any existing component without having to worry about how data will flow down from parents.
So, are you trying to suggest that I should not use containers/ renderers at all apart from one call to
IsomorphicRelay.Rederer
made inrenderOnServer.js
?
You should never render Rederer
or RootContainer
yourself when using isomorphic-relay-router. See the ToDo example in the isomorphic-relay-router repository. Also see the documentation for react-router-relay about how to correctly configure routes.