-
Notifications
You must be signed in to change notification settings - Fork 27.6k
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
Minimal Relay example #106
Comments
Any success? |
I have yet to try it... mostly today? |
Im new too
|
Or in general, how to add a GraphQL client? E.g Apollo (which unlike Relay 1 is fully GraphQL compliant)? 0.5.0 just came out. |
I created a higher order component to wrap routes that take data from apollo: import React from 'react'
import 'isomorphic-fetch'
import ApolloClient, { createNetworkInterface } from 'apollo-client'
import { getDataFromTree } from "react-apollo/server"
import { ApolloProvider } from 'react-apollo'
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
const getReducer = ( client ) => {
return combineReducers({
apollo: client.reducer( ),
someReducer: ( state = {}, action = null ) => action && action.state
? action.state
: state
});
}
const getClient = ( headers ) => {
return new ApolloClient({
networkInterface: createNetworkInterface({ uri: 'http://mygraphqlserver.local/graphql' }),
ssrMode: true,
headers: headers
})
}
export const initClientAndStore = ( initialState, isServer, headers ) => {
if ( isServer && typeof window === 'undefined' ) {
const client = getClient( headers )
return {
client,
store: createStore(getReducer( client ), initialState, applyMiddleware(client.middleware( )))
}
} else {
if ( !window.clientAndStore ) {
const client = getClient( headers )
window.clientAndStore = {
client,
store: createStore(getReducer( client ), initialState, compose( applyMiddleware(client.middleware( )), window.devToolsExtension
? window.devToolsExtension( )
: f => f ))
}
}
return window.clientAndStore
}
}
const getRootComponent = ( {
client,
store
}, Component ) => (
<ApolloProvider client={client} store={store}>
<Component prop={'test'}/>
</ApolloProvider>
)
export default( ComposedComponent ) => class WrapWithApollo extends React.Component {
static async getInitialProps({ req }) {
const isServer = !!req
const headers = req
? req.headers
: {}
const clientAndStore = initClientAndStore( {}, isServer, headers );
await getDataFromTree(getRootComponent( clientAndStore, ComposedComponent ))
return { initialState: clientAndStore.store.getState( ), isServer, headers }
}
constructor( props ) {
super( props )
const clientAndStore = initClientAndStore( props.initialState, props.isServer, props.headers );
this.clientAndStore = clientAndStore;
}
render( ) {
return getRootComponent( this.clientAndStore, ComposedComponent )
}
} it mostly works, but im getting a strange warning about the markup checksum:
|
@thorstenweber83 that looks like a react Apollo SSR bug we are tracking and hope to have fixed soon! This looks pretty great. I'd love to create a |
A general package for Apollo (with SSR) + next.js would be awesome indeed, I've been sketching a little myself on something similar but didn't get very far yet. I'd be glad to just help out testing if you guys need any assistance. |
@thorstenweber83 I haven't figured out how I can configure the endpoint URI through an environment variable. Client-side, it seems the constructor calls |
I took @thorstenweber83's code and wrapped to take care of the https://github.com/sedubois/realate/blob/master/containers/Apollo.js Apologies if there are any mistakes, but at least it works so far. Would be great if newcomers didn't have to figure out all of that by themselves. |
It's really surprising to me that it's this hard to set up a global container, like Redux, with this framework. Is there an official answer for how to use Redux with Next.js? |
Ah, I found the wiki page, I guess it suggests something similar. Perhaps someone can maintain a package like |
@stubailo I think that's what @jbaxleyiii had in mind, I think it would be great too 😊 Maybe things could also be further simplified with #88. |
In the first example I gave above, the data is only rendered client-side. But how to render Apollo server-side? @thorstenweber83, above you render server-side with @stubailo In your GitHunt example, you do SSR using react-router which passes the props for rendering, but I don't know how to do it without react-router. Help appreciated 😊 |
OK I'm starting to understand this So I did that but then got server-side |
Related issue: apollographql/apollo-client#645 |
OK as for lacking SSR, my problem came from having wrapped in a higher-order component and not re-calling |
Has anyone been able to put together a working example of next.js and apollo-client? |
Yes @ads1018, here! https://github.com/relatecommunity/relate I'll get back to work on it in a few days, but already has Next and Apollo. |
Guys, Next.js had a pretty big issue with #253. With now Anyway, we should have some example showcasing that. |
@arunoda amazing news! I've been itching to use next.js for my next project but have been holding off until it plays nice with apollo-client. Looking forward to checking out the example. |
Same here, I really look forward to seeing some examples with |
I posted an example with apollo in #387 - thought I'd create a new issue since it's not about relay. |
One problem, when using isomorphic-relay, is that
And passing it into
But, as the author of isomorphic-relay said in that issue, this isn’t really ideal. Another thing to keep in mind is that if you are thinking of using a hosted graphql service like Graphcool it might not be worth going with relay server rendering anyway. You’re looking at ~1 second waiting for a response from the service and the subsequent initial server render. |
@thisbejim I agree, I only went with Graphcool because it was easy to setup and wouldn't litter the repo with graphql schema related files and dependencies. I'd like to finish the next.js example, though I don't know how to properly initialize the Relay enviornment, if someone has an idea or interest in it, here's the repo: And my current issue: |
I wish Relay's API was isomorphic out of the box, but that just doesn't seem to be a priority for FB atm. |
I wonder if we should keep this open or not. Maybe we should just document the reason why using Apollo over Relay is better in the case of isomorphic rendering. |
I'd definitely keep this open, imo apollo-client and Relay are too far apart to consider them just a replacements of each other. While apollo might get more primitives right, there are things I really like about Relay they that apollo gets wrong:
Maybe I'll find the time to figure out how exactly the Relay API would have to change, to make the integration with next simpler. |
I don't have a strong opinion on whether or not to close this issue (if I had to choose, I would say keep it open), but I just wanted to address the points made by @Gregoor, because I think they aren't valid (to be fair, the fragment one used to be valid). While neither is a drop-in replacement of the other, I think it's worth pointing out that with Apollo you can do everything that you can do with Relay, but not the other way around. To address the specific points made:
while in Apollo it can be simply this:
Which one you prefer might be a matter of taste, but I'm willing to bet that most people will find the second query much easier to understand and aesthetically more pleasing. If you want to use the first style of query, you can still do that in Apollo, but you cannot use the second style of query in Relay. note: I intentionally used long ids in the Relay example, because Relay requires all ids to be unique across your schema. PS: we're planning to add special support to make cursor-based pagination super-easy in one of the upcoming versions of Apollo.
Now that said, I agree 100% with you that neither should be considered a replacement of the other, and that each client has its own strengths and weaknesses. Personally I think it would be great if Relay was easier to use and integrated better with other libraries, @Gregoor I would love to know what things you wish Apollo did/had that Relay currently does/has. We're always striving to make Apollo better, so your input would be much appreciated and valued! I also hope that once Relay 2 finally comes out it will be possible to use it with next.js. I'm also hoping that there will be some really innovative features in it that we can adopt in Apollo as well 😀 |
Thanks @helfer, intriguing points!
Dang, that's a bit sad. Related Thread is here btw, for anyone that's interested. I hope it gets reimplemented at some later point.
|
I would be surprised if you don't have to do that in Relay 2 because it makes static analysis quite a bit more difficult. Perhaps they require you to use a variable name that's identical to the fragment name or something.
That's also a Relay 1-specific feature, I don't think Relay 2 has it because of the move to static queries. |
Yaiks, I hope it doesn't turn out that way, then Relay 2 would be quite the downgrade for me. I really do appreciate the isolation of variable setting in Relay and if Relay 2 is more apollo like that would make it a lot more complex wouldn't it? I feel like I'm missing something here. |
I think the general Apollo vs. Relay debate is very interesting but a bit off-topic concerning Next.js 😄 If we agree Relay 1 can't practically be integrated with Next.js, I'd just close the issue. And we can reopen a new one when Relay 2 is a thing. @timneutkens ? |
We might have gotten a bit sidetracked true 😁 I added another commit to https://github.com/Gregoor/next.js-relay-example which makes it kinda work. The kinda part is, that there is just no proper way to rehydrate Relay, so the first client-side render is empty (and thereby inequal to the server's render) but without refetching the client renders again correctly. Atm I don't see any API in Relay that would allow completely fixing it, so closing this is fine from my side. |
Closing in favor of #1757 |
How can I use relay to populate my data? Will it work automatically? or any plans on how to add support for it?
The text was updated successfully, but these errors were encountered: