Skip to content

Latest commit

 

History

History
64 lines (39 loc) · 4.08 KB

README.md

File metadata and controls

64 lines (39 loc) · 4.08 KB

Redux Thunk example

This example shows how to integrate Redux and Redux Thunk in Next.js.

Usually splitting your app state into pages feels natural but sometimes you'll want to have global state for your app. This is an example on how you can use redux that also works with Next.js's universal rendering approach.

Deploy your own

Deploy the example using ZEIT Now:

Deploy with ZEIT Now

How to use

Using create-next-app

Execute create-next-app with npm or Yarn to bootstrap the example:

npm init next-app --example with-redux-thunk with-redux-thunk-app
# or
yarn create next-app --example with-redux-thunk with-redux-thunk-app

Download manually

Download the example:

curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-redux-thunk
cd with-redux-thunk

Install it and run:

npm install
npm run dev
# or
yarn
yarn dev

Deploy it to the cloud with ZEIT Now (Documentation).

Notes

The Redux Provider is implemented in pages/_app.js. The MyApp component is wrapped in a withReduxStore function, the redux store will be initialized in the function and then passed down to MyApp as this.props.initialReduxState, which will then be utilized by the Provider component.

Every initial server-side request will utilize a new store. However, every Router or Link action will persist the same store as a user navigates through the pages. To demonstrate this example, we can navigate back and forth to /show-redux-state using the provided Links. However, if we navigate directly to /show-redux-state (or refresh the page), this will cause a server-side render, which will then utilize a new store.

In the clock component, we are going to display a digital clock that updates every second. The first render is happening on the server and then the browser will take over. To illustrate this, the server rendered clock will initially have a black background; then, once the component has been mounted in the browser, it changes from black to a grey background.

In the counter component, we are going to display a user-interactive counter that can be increased or decreased when the provided buttons are pressed.

This example includes two different ways to access the store or to dispatch actions:

1.) pages/index.js will utilize connect from react-redux to dispatch the startClock redux action once the component has been mounted in the browser.

2.) components/counter.js and components/examples.js have access to the redux store using useSelector and can dispatch actions using useDispatch from react-redux@^7.1.0

You can either use the connect function to access redux state and/or dispatch actions or use the hook variations: useSelector and useDispatch. It's up to you.

This example also includes hot-reloading when one of the reducers has changed. However, there is one caveat with this implementation: If you're using the Redux DevTools browser extension, then all previously recorded actions will be recreated when a reducer has changed (in other words, if you increment the counter by 1 using the +1 button, and then change the increment action to add 10 in the reducer, Redux DevTools will playback all actions and adjust the counter state by 10 to reflect the reducer change). Therefore, to avoid this issue, the store has been set up to reset back initial state upon a reducer change. If you wish to persist redux state regardless (or you don't have the extension installed), then in store.js change (line 19) store.replaceReducer(createNextReducer(initialState)) to store.replaceReducer(createNextReducer).