redux-universal-promise
v0.1.0-0
Published
Redux middleware for async action supporting universal (server-side) rendering
Downloads
1
Maintainers
Readme
redux-universal-promise
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.