CrocoDillon / universal-react-redux-boilerplate

Step by step creation of a Universal React + Redux Boilerplate
Other
176 stars 33 forks source link

How to integrate GraphQl? #15

Closed developer239 closed 7 years ago

developer239 commented 7 years ago

Could you please create branch or in other way show me how to use graphql? I know how to connect it to normal react / redux apps but I have no idea how to solve server side rendering.

It is possible to use https://www.graph.cool/ as a server so you do not need to bloat your application with API. I am interested in the client side only.

By the way thank you for your work. This looks really cool. There are not many react / redux universal templates that use webpack 2. Your setup is also really fast.

developer239 commented 7 years ago

Totally forgot about this one. I eventually made it working like this:

store:

import { createStore, compose, applyMiddleware } from 'redux';
import { syncHistoryWithStore, routerMiddleware } from 'react-router-redux';
import thunk from 'redux-thunk';
import { browserHistory } from 'react-router';

import rootReducer from 'rootReducer';
import client from 'config/apolloClient';
import { isDeveloping } from 'config';

/* See: https://github.com/reactjs/react-router-redux/issues/305 */
const isClient = typeof document !== 'undefined';

// Initial state, I prefer to have this empty and initialize state in reducers themselves
const initialState = {};

const routingMiddleware = routerMiddleware(browserHistory);
const middlewares = [thunk, routingMiddleware, client.middleware()];

const enhancers = [];
if (isClient && isDeveloping) {
  const devToolsExtension = window.devToolsExtension;
  if (typeof devToolsExtension === 'function') {
    enhancers.push(devToolsExtension());
  }
}

const composedEnhancers = compose(
  applyMiddleware(...middlewares),
  ...enhancers,
);

const store = createStore(
  rootReducer,
  initialState,
  composedEnhancers,
);

export const history = isClient ?
  syncHistoryWithStore(browserHistory, store) : undefined;

// Reducer hot module replacement
if (module.hot) {
  module.hot.accept('rootReducer', () => {
    const nextRootReducer = require('rootReducer').default;
    store.replaceReducer(nextRootReducer);
  });
}

export default store;

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';

// Makes hot module replacement possible
import { AppContainer } from 'react-hot-loader';

// This is our App with ApolloProvider and Router
import RouterApp from 'routes';

const render = (Component) => {
  ReactDOM.render(
    <AppContainer>
      <Component />
    </AppContainer>,
    document.getElementById('root')
  );
};

// Render App
render(RouterApp);

// Render App with hot module replacements
if (module.hot) {
  module.hot.accept('routes', () => {
    const NewApp = require('routes').default;
    render(NewApp);
  });
}

Everything else is in the documentation.

CrocoDillon commented 7 years ago

Thanks @developer239, I'm sorry but haven't had the chance to work on this project for a while plus I just got back from vacation. I hope your solution will help others as well!

developer239 commented 7 years ago

That is ok. Thank you for your work anyway. I created my own boilerplate. I still need to add the server side rendering though. That might take me a while. :)

https://github.com/developer239/ReactReduxApolloGraphQLHotBoilerplate