0.1.0-0 • Published 7 years ago

redux-universal-promise v0.1.0-0

Weekly downloads
4
License
MIT
Repository
github
Last release
7 years ago

redux-universal-promise

npm version MIT-licensed

Promise middleware for Redux supporting universal rendering with React and similar frameworks.

Usage

Components

Container components that need access data should dispatch fetch actions in componentWillMount.

Actions

Use standard actions whose payload is a Promise. Middleware will intercept the action, wait for the Promise to complete, then dispatch the action with its payload set to the Promise's result (and an error: true) property added to the action if the Promise is rejected.

Middleware

import {createStore, applyMiddleware} from 'redux'
import {promiseMiddleware} from 'redux-universal-promise'

import reducers from './reducers'

const __ON_SERVER__ = ... // your code needs some way to know where it's running

export default createStore(
  reducers,
  applyMiddleware(
    promiseMiddleware(__ON_SERVER__)
  )
)

Server-side rendering

Instead of using (e.g.) React's renderToString directly, use renderOnServer in this library. Your app will be rendered, and the middleware will collect all Promises from actions dispatched during rendering. Promise.all() is used to wait for them to finish, then your app is rendered once again, giving your desired server-side rendered app.

import express from 'express'
import {renderToString} from 'react-dom/server'
import {Provider} from 'react-redux'
import {renderOnServer} from 'react-universal-promise'
import {Router} from 'universal-react-router'

import routes from './routes'
import store from './store'

const app = express()

app.get('*', (req, res) => {
  return renderOnServer(
    store,
    renderToString,
    <Provider store={store}>
      <Router routes={routes} />
    </Provider>
  )
    .then((output) => `
      <!doctype html>
      ...
      ${output}
      ...
      <script>window.state = ${JSON.stringify(store.getState())}</script>
    `)
    .catch(({output, error}) => {
      // If any of the Promises is rejected, your app will still be rendered again,
      // as your components probably already handle errors and have appropriate UI.
    })
})

Status

I wrote this library because I couldn't find a way to build a universal Redux app cleanly. If you find it works for you, it will likely continue working, but it should be considered experimental.

If you use it / would like to use it, feel free to open issues to nag me to improve the library or documentation.