Skip to content

Redux module for universal render with async fetching data.

Notifications You must be signed in to change notification settings

StefanoPastore/redux-universal-render

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Redux Universal render

Build Status Coverage Status

Dependencies

redux-thunk

Why you need?

It is necessary because you must wait data is loaded before render page on server side.

Installation

To install the stable version with npm:

npm install --save redux-universal-render

Usage

This module supply for you reducer and render function to apply on server and client.

Example store config:

import { createStore, compose, applyMiddleware, combineReducers } from 'redux';
import { reducer as reduxUniversalRenderReducer } from 'redux-universal-render';
import thunk from 'redux-thunk';
import * as reducers from './reducers';

const initialState = {};

const store = createStore(
  combineReducers({ ...reducers, reduxUniversalRenderReducer }),
  initialState,
  compose(applyMiddleware(thunk))
);

Example server side rendering:

import { awaitRender } from 'redux-universal-render';

match({ routes, location: req.originalUrl }, (error, redirectLocation, renderProps) => {
    const render = <Provider store={store}>
      <RouterContext {...renderProps} />
    </Provider>;
    awaitRender({
      store,
      render,
      cb: () => {
        const content = renderToString(render);
        const page = renderToStaticMarkup(<HTML content={content} />);

        res.send(`<!doctype html>\n${page}`);
      }
    }
    );
  });
});

Example actions creators:

import { isParsed, addAction, parsedAction } from 'redux-universal-render';

export const syncActionCreator = () => ({ type: 'ACTION' });

const asyncName = 'asyncName';
export const asyncAction = () => (dispatch, getState) => {
  // not refetch data if it is already parsed for ssr and client render
  if (isParsed(asyncName)(getState())) return;

  dispatch(addAction(asyncName));
  setTimeout(() => {
    dispatch(syncActionCreator());
    dispatch(parsedAction(asyncName));
  }, 200);
};

actions

  • addAction: This action add to pending async actions with unique name.

Example:

import { addAction } from 'redux-universal-render';

const name = 'action';
export const action = () => (dispatch) => {
  dispatch(addAction(name));
}
  • parsedAction: This action set ended a specific async action by same name adedd with addAction.

Example:

import { addAction, parsedAction } from 'redux-universal-render';

const name = 'action';
export const action = () => async (dispatch) => {
  dispatch(addAction(name));
  // your async logic
  dispatch(parsedAction(name));
}
  • errorAction: This action set in error a specific async action by same name adedd with addAction.

Example:

import { addAction, errorAction } from 'redux-universal-render';

const name = 'action';
export const action = () => async (dispatch) => {
  dispatch(addAction(name));
  try {
    // your async logic
  } catch(e) {
    dispatch(errorAction(name, e));
  }
}

selectors

  • inExecution: return true if there is async actions in queue

  • isEnded: return true if there isn't async actions in queue

  • actions: return array of actions in queue

  • parsed: return array of actions already parsed

  • errors: return object with action name: error

  • isPending: return true if action name is added in queue

  • isParsed: return true if action name is already parsed

  • isError: return true if action name is in error

API

  • awaitRender({

    • store (required): Redux store
    • render component (required): React component to render
    • cb (required): Function, it is called when all async actions dispatched are ended
    • ownerRender(walk) (optional): Function, receive function that render component you must call it can you wrap with your own business logic

})

  • createActions(

    • name: string or function that receive getState and return unique name for actions
    • action: async action to await

)

Example:

import { createActions } from 'redux-universal-render';

createActions((getState) => `name_${getState().myVar}`, async (dispatch, getState) => {
  // ... my logic
});

About

Redux module for universal render with async fetching data.

Resources

Stars

Watchers

Forks

Packages

No packages published