redux universal
Post on 24-Jan-2018
1.810 Views
Preview:
TRANSCRIPT
Redux Universalby Sebastian Siemssen & Nik Graf
Redux Universal @nikgraf
Nik Graf@nikgraf
nik@nikgraf.com
Creator of Belle
Working with StarterSquad
History
Redux Universal @nikgraf
Server side rendering• (Client) Request the website's HTML
• (Server) Execute the Code
• (Server) Collect the data
• (Server) Render the page in the backend
• (Server) Serve the page with content
• (Client) -> Render the content
Redux Universal @nikgraf
?
Universal Rendering
Redux Universal @nikgraf
Benefits
• Search Engine Indexability
• Code Reusability & Maintainability
• Faster Perceived Load Time !?
Redux Universal @nikgraf
Client side rendering• (Client) Request the website's HTML
• (Server) Serve the page without content
• (Client) Request JavaScript code based on sources in the HTML
• (Server) Serve the JavaScript code
• (Client) Load & execute JavaScript
• (Client) -> Render a loading page
• (Client) Request data based on the executed code
• (Server) Collect and serve the data
• (Client) -> Render the content
Redux Universal @nikgraf
Isomorphic Universal rendering• (Client) Request the website's HTML
• (Server) Execute the JavaScript Code
• (Server) Collect the data
• (Server) Render the page in the backend
• (Server) Serve the page with content
• (Client) -> Render the content
• (Client) Request JavaScript code based on sources in the HTML
• (Server) Serve the JavaScript code
• (Client) Load & execute JavaScript
Redux Universal @nikgraf
Render on the Server (React)
import React, { Component } from 'react';import { renderToString } from 'react-dom/server';
class MyComponent extends Component { render() { return <div>Hello World</div>; }}
const html = renderToString(MyComponent);
Redux Universal @nikgraf
Render on the Server (React/Redux)
import { renderToString } from 'react-dom/server';import { createStore } from 'redux';import { Provider } from 'react-redux';import rootReducer from '../reducers';import App from '../components/App';
const store = createStore(rootReducer);const html = renderToString( <Provider store={store}> <App/> </Provider>);
Redux Universal @nikgraf
Redux on the Server I/IIIimport ReactDOM from 'react-dom';import { createStore } from 'redux';import { Provider } from 'react-redux';import rootReducer from '../reducers';import App from '../components/App';
const initialState = window.__INITIAL_STATE__;const store = createStore(rootReducer, initialState);
const rootElement = document.getElementById('app');
ReactDOM.render( <Provider store={store}><App/></Provider>, rootElement);
Redux Universal @nikgraf
Redux on the Server II/IIIconst renderFullPage = (html, initialState) => { return ` <!doctype html> <html> <body> <div id="app">${html}</div> <script> window.__INITIAL_STATE__ = ${JSON.stringify(initialState)}; </script> <script src="/static/bundle.js"></script> </body> </html> `;}
Redux Universal @nikgraf
Redux on the Server III/III
app.use((request, response) => { const store = createStore(rootReducer); const html = renderToString( <Provider store={store}> <App/> </Provider> ); const state = store.getState(); response.send(renderFullPage(html, state));});
Redux Universal @nikgraf
What about async actions?
Redux Universal @nikgraf
Async Action Exampleimport fetch from 'isomorphic-fetch';
export function fetchFriends() { return dispatch => { dispatch({ type: 'FETCH_FRIENDS' }); return fetch('http://localhost/api/friends/') .then(response => response.json()) .then(json => { dispatch({ type: 'RECEIVE_FRIENDS', payload: json }); }); };}
Redux Universal @nikgraf
Issue with Async
Async ActionRender
RenderAsync Action
Redux Universal @nikgraf
Before using redux-universalimport { createStore, applyMiddleware } from 'redux';import thunk from 'redux-thunk';import rootReducer from '../reducers';
const createStoreWithMiddleware = applyMiddleware( thunk)(createStore);
export default function configureStore(initialState) { return createStoreWithMiddleware(rootReducer, initialState);}
Redux Universal @nikgraf
Using redux-universalimport { createStore } from 'redux';import thunk from 'redux-thunk';import rootReducer from '../reducers';
const applyMiddleware = __SERVER__ ? require('redux-universal') : require('redux').applyMiddleware;
const createStoreWithMiddleware = applyMiddleware( thunk)(createStore);
export default function configureStore(initialState) { return createStoreWithMiddleware(rootReducer, initialState);}
Redux Universal @nikgraf
Before using redux-universal
const html = renderToString( <Provider store={store}> <App/> </Provider>);const state = store.getState();res.send(renderFullPage(html, state));
Redux Universal @nikgraf
Using redux-universalstore.renderUniversal( renderToString, <Provider store={store}> <App/> </Provider> ) .then(({ output }) => { const state = store.getState(); response.send(renderFullPage(output, state)); }) .catch(({ output, error }) => { console.warn(error.message); });
Redux Universal @nikgraf
How it works
-> render
-> wait for promise
-> render
-> resolve
Redux Universal @nikgraf
How it works-> render
-> wait for promiseA
-> render
-> wait for promiseB
-> render
-> resolve
Redux Universal @nikgraf
Fin
Checkout Redux Universal
https://github.com/reducks/redux-universal
top related