I am totally new to react-apollo I am pretty confused that how to rehydrate state from the server side to client And my app is working, But the problem is it is not using preloaded state from Apollo After component rendered it is calling the API again.
Seriously Redux Integration Makes Complicated only Apollo state is rendering not the custom redux state that's the problem here.But I don;t know how to integrate.
Server.js
const HTML = ({ html,state}) => (
<html lang="en" prefix="og: http://ogp.me/ns#">
<head>
<meta charSet="utf-8" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta httpEquiv="Content-Language" content="en" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div
id="app"
dangerouslySetInnerHTML={{ __html: html }} />
<script dangerouslySetInnerHTML={{
__html: `window.__STATE__=${JSON.stringify(state)};`,
}} />
<script src="/static/app.js" />
</body>
</html>
);
app.get('/*',(req,res) => {
const routeContext = {};
const client = serverClient();
const components = (
<StaticRouter location={req.url} context={routeContext}>
<ApolloProvider store={store} client={client}>
<WApp />
</ApolloProvider>
</StaticRouter>
);
getDataFromTree(components).then(() => {
const html = ReactDOMServer.renderToString(components);
const initialState = {apollo: client.getInitialState()}
res.send(`<!DOCTYPE html>\n${ReactDOMServer.renderToStaticMarkup(
<HTML
html={html}
state={initialState}
/>,
)}`)
})
})
apolloClient.js
import ApolloClient, {
createNetworkInterface,
addTypeName,
} from 'apollo-client';
const isProduction = process.env.NODE_ENV !== 'development';
const testUrl = 'http://localhost:3000/api';
// const url = isProduction ? productionUrl : testUrl;
const url = testUrl;
const client = new ApolloClient({
networkInterface: createNetworkInterface({uri:testUrl}),
dataIdFromObject:({id}) => id,
reduxRootKey:state => state.apollo,
initialState: (typeof window !=='undefined')? window.__STATE__:{}
});
export default client;
store.js
import { createStore, compose, applyMiddleware } from 'redux';
import { syncHistoryWithStore } from 'react-router-redux';
import thunk from 'redux-thunk';
import {createLogger} from 'redux-logger';
import client from '../apolloClient';
import rootReducer from '../Reducers'
//All Reducer
import {initialState as allPosts} from '../Reducers/AllPosts_Reucer';
const isProduction = process.env.NODE_ENV !== 'development';
const isClient = typeof document !== 'undefined';
const initialState = {
allPosts
};
const middlewares = [thunk, client.middleware()];
const enhancers = [];
if (!isProduction && isClient) {
const loggerMiddleware = createLogger();
middlewares.push(loggerMiddleware);
if (typeof devToolsExtension === 'function') {
const devToolsExtension = window.devToolsExtension;
enhancers.push(devToolsExtension());
}
}
const composedEnhancers = compose(
applyMiddleware(...middlewares),
...enhancers
);
const store = createStore(
rootReducer,
initialState,
composedEnhancers,
);
export default store;
Sample Component
import React,{Component} from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
import * as postActions from '../../Redux/Actions/postActions';
class Home extends Component{
componentWillMount(){
// console.log('From Will Mount',this.props.posts)
}
renderAllPost(){
const {loading,posts} = this.props;
if(!loading){
return posts.map(data => {
return <li key={data.id}>{data.title}</li>
})
}else{
return <div>loading</div>
}
}
render(){
console.log(this.props);
return(
<div>
{this.renderAllPost()}
</div>
)
}
}
//start from here
const GetallPosts = gql`
query getAllPosts{
posts{
id
title
body
}
}
`;
// const mapStateToPros = (state) => ({
// allPosts:state.allPosts
// });
const mapDispatchToProps = (dispatch) => ({
actions:bindActionCreators(
postActions,
dispatch
)
});
const ContainerWithData = graphql(GetallPosts,{
props:({ data:{loading,posts} }) => ({
posts,
loading,
})
})(Home)
export default connect(
// mapStateToPros,
// mapDispatchToProps
)(ContainerWithData)
Apollo Client provides a handy API for using it with server-side rendering, including a function that executes all of the GraphQL queries that are required to render your component tree. You don't need to make any changes to your queries to support this API.
Since the first rule of hooks is that they must only be called at the top level (client-side), you cannot use them in server-side functions. No, you cannot run useQuery in the Next SSR or SSG functions.
Resetting the cache Sometimes, you might want to reset the cache entirely, such as when a user logs out. To accomplish this, call client. resetStore . This method is asynchronous, because it also refetches any of your active queries.
GraphQL is often explained as a frontend-focused API technology because it enables clients to get data in a much nicer way than before. But the API itself is, of course, implemented on the server side.
You can inject the redux-persist state directly into apollo-client with
getStoredState({ storage: localforage }, (err, rehydratedState) => { ... }
also i wish there was a different approach, check for Delay Render Until Rehydration Complete
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With