Skip to content

Instantly share code, notes, and snippets.

@mikker
Last active January 11, 2017 13:10
Show Gist options
  • Save mikker/3787f4b1d90c9eaa9057edaeb8dc16c4 to your computer and use it in GitHub Desktop.
Save mikker/3787f4b1d90c9eaa9057edaeb8dc16c4 to your computer and use it in GitHub Desktop.
Higher Order Function for Redux with Next.js
import { Component } from 'react'
import { Provider, connect } from 'react-redux'
import { reducer, initStore } from './store'
export default function Connected (...args) {
return function (Comp) {
return class StoreComponent extends Component {
static getInitialProps ({ req }) {
const isServer = !!req
const store = initStore(reducer, undefined, isServer)
return { initialState: store.getState(), isServer }
}
constructor (props) {
super(props)
this.store = initStore(reducer, props.initialState, props.isServer)
}
render () {
const ConnComp = connect.apply(this, args)(Comp)
return <Provider store={this.store}>
<ConnComp />
</Provider>
}
}
}
}
import { update } from '../store'
import Connected from '../Connected'
import Layout from '../components/Layout'
// Connected(..) takes same arguments as connect(..) from react-redux
export default Connected(state => state)(({ query, dispatch }) =>
<Layout>
<h1>{query}</h1>
<button onClick={() => { dispatch(update({query: 'clicked'})) }}>
CLICK
</button>
</Layout>
)
import { createStore, applyMiddleware, compose } from 'redux'
import promise from 'redux-simple-promise'
const initialState = {
query: 'test'
}
export const reducer = (state = initialState, action) => {
switch (action.type) {
case 'UPDATE': return { ...state, ...action.payload }
default: return state
}
}
export const update = (changes) =>
({ type: 'UPDATE', payload: changes })
export const initStore = (reducer, initialState, isServer) => {
if (isServer && typeof window === 'undefined') {
return createStore(reducer, initialState, applyMiddleware(promise()))
} else {
if (!window.store) {
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
window.store =
createStore(reducer, initialState, composeEnhancers(
applyMiddleware(promise()))
)
}
return window.store
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment