Redux Eggs wrapper for Next.js
Redux Eggs wrapper for Next.js applications. This library works in a similar way to Next Redux Wrapper.
Contents:
Installation:
If you are using Yarn, run
yarn add @redux-eggs/core @redux-eggs/next
If you are using NPM, run
npm install --save @redux-eggs/core @redux-eggs/next
-
next
11.1.0 and newer -
react
16.8.3 and newer -
react-redux
7.0.0 and newer
Usage
Create your store:
import { createWrapperInitializer } from '@redux-eggs/next'
import { createStore } from '@redux-eggs/redux-toolkit'
import { combineReducers } from '@reduxjs/toolkit'
const reducerCombiner = (reducersMap: ReducersMapObject) => {
const combinedReducer = combineReducers(reducersMap)
return (state: any = {}, action: AnyAction) => {
return combinedReducer(action.type === StoreActionType.HYDRATE ? { ...state, ...action.payload } : state, action)
}
}
const createAppStore = () => createStore({ reducerCombiner })
export const wrapperInitializer = createWrapperInitializer(createAppStore, {
hydrationActionType: StoreActionType.HYDRATE,
})
Wrap your App:
import { Layout } from '../components/layout'
import { getCommonEgg } from '../eggs/common'
import { wrapperInitializer } from '../store'
const CustomApp = ({ Component, pageProps }) => {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
const beforeResult = async store => {
if (typeof window === 'undefined') {
// ...any async tasks for SSR
}
}
const wrapper = wrapperInitializer.getAppWrapper([getCommonEgg()], { beforeResult })
export default wrapper.wrapApp(CustomApp)
Wrap your Error Page:
import { wrapperInitializer } from '../store'
const ErrorPage = () => {
return (
<div>
<h1>ERROR</h1>
</div>
)
}
const wrapper = wrapperInitializer.getPageWrapper()
// Use this if your wrapper for `_app` has `beforeResult` function
export const getStaticProps = wrapper.wrapGetStaticProps()
export default wrapper.wrapPage(ErrorPage)
Wrap your page like this:
import { Posts } from '../components/posts'
import { getPostsEgg } from '../eggs/posts'
import { loadPosts } from '../eggs/posts/slice'
import { wrapperInitializer } from '../store'
const wrapper = wrapperInitializer.getPageWrapper([getPostsEgg()])
const PostsPage = wrapper.wrapPage(({ title }) => {
return (
<div>
<h1>{title}</h1>
<Posts />
</div>
)
})
export const getStaticProps = wrapper.wrapGetStaticProps(store => () => {
store.dispatch(loadPosts())
return {
props: {
title: 'Posts',
},
}
})
export default PostsPage
...or like this:
import { Posts } from '../components/posts'
import { getPostsEgg } from '../eggs/posts'
import { loadPosts } from '../eggs/posts/slice'
import { wrapperInitializer } from '../store'
const wrapper = wrapperInitializer.getPageWrapper([getPostsEgg()])
const PostsPage = wrapper.wrapPage(({ title }) => {
return (
<div>
<h1>{title}</h1>
<Posts />
</div>
)
})
export const getServerSideProps = wrapper.wrapGetServerSideProps(store => async () => {
store.dispatch(loadPosts())
return {
props: {
title: 'Posts',
},
}
})
export default PostsPage
...or like this:
import { Posts } from '../components/posts'
import { getPostsEgg } from '../eggs/posts'
import { loadPosts } from '../eggs/posts/slice'
import { wrapperInitializer } from '../store'
const wrapper = wrapperInitializer.getPageWrapper([getPostsEgg()])
const PostsPage = wrapper.wrapPage(({ title }) => {
return (
<div>
<h1>{title}</h1>
<Posts />
</div>
)
})
PostsPage.getInitialProps = wrapper.wrapGetInitialProps(store => () => {
store.dispatch(PostsPublicAction.loadPosts())
return {
title: 'Posts',
}
})
export default PostsPage