|
| 1 | +# Boilerplate for Next Redux Wrapper with Redux Persist (& redux-thunk too) for a Next Js project |
| 2 | + |
| 3 | +My problem was that I needed a simple persistent global state for my Next.js website. This is a redux boilerplate and I wrote it for myself at first to speed up my future project. You may need this code to understand the process. If you want to use this in your project, feel free to use it. |
| 4 | + |
| 5 | +Using a persistent global state in a Next js website is much more daunting than I thought! See my [twitter](https://twitter.com/fazlulkarimweb/status/1266463218265812992). You have to have a solid understanding of client-side and server-side rendering & how Next js is dealing with it! Obviously don't forget about the persistency feature and some performance drawbacks of in case of server-side rendering. So I created this boilerplate with a counter app example. |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +## Why this boileplate? |
| 10 | + |
| 11 | +Let's face it. Everyone hates boilerplate code! Me too. But redux is a exception. Copy and pasting redux boilerplate code without understanding seems a norm to people who are relatively new to the redux ecosystem. If you are new to redux, you may use this boilerplate to copy and paste and attain the functionality right away. Okay, you can do this. But it will be more helpful, if you understand the code and implement it by yourself. You may take the help from this boilerplate code. I didn't find a boilerplate like this in the next js example section. I decided to write one for myself! |
| 12 | + |
| 13 | +## Enough Talk, Show me the code |
| 14 | + |
| 15 | +What should be the structure of your redux store? |
| 16 | + |
| 17 | +```javascript |
| 18 | +// ./store/store |
| 19 | + |
| 20 | +import { createStore, applyMiddleware, combineReducers } from "redux"; |
| 21 | +import { createWrapper, HYDRATE } from "next-redux-wrapper"; |
| 22 | +import thunkMiddleware from "redux-thunk"; |
| 23 | +import counter from "../store/counter/reducer"; |
| 24 | + |
| 25 | +//COMBINING ALL REDUCERS |
| 26 | +const combinedReducer = combineReducers({ |
| 27 | + counter, |
| 28 | + // OTHER REDUCERS WILL BE ADDED HERE |
| 29 | +}); |
| 30 | + |
| 31 | +// BINDING MIDDLEWARE |
| 32 | +const bindMiddleware = (middleware) => { |
| 33 | + if (process.env.NODE_ENV !== "production") { |
| 34 | + const { composeWithDevTools } = require("redux-devtools-extension"); |
| 35 | + return composeWithDevTools(applyMiddleware(...middleware)); |
| 36 | + } |
| 37 | + return applyMiddleware(...middleware); |
| 38 | +}; |
| 39 | + |
| 40 | +const makeStore = ({ isServer }) => { |
| 41 | + if (isServer) { |
| 42 | + //If it's on server side, create a store simply |
| 43 | + return createStore(combinedReducer, bindMiddleware([thunkMiddleware])); |
| 44 | + } else { |
| 45 | + //If it's on client side, create a store with a persistability feature |
| 46 | + const { persistStore, persistReducer } = require("redux-persist"); |
| 47 | + const storage = require("redux-persist/lib/storage").default; |
| 48 | + |
| 49 | + const persistConfig = { |
| 50 | + key: "nextjs", |
| 51 | + whitelist: ["counter"], // make sure it does not clash with server keys |
| 52 | + storage, |
| 53 | + }; |
| 54 | + |
| 55 | + const persistedReducer = persistReducer(persistConfig, combinedReducer); |
| 56 | + const store = createStore( |
| 57 | + persistedReducer, |
| 58 | + bindMiddleware([thunkMiddleware]) |
| 59 | + ); |
| 60 | + store.__persistor = persistStore(store); |
| 61 | + return store; |
| 62 | + } |
| 63 | +}; |
| 64 | + |
| 65 | +// export an assembled wrapper |
| 66 | +export const wrapper = createWrapper(makeStore); |
| 67 | +``` |
| 68 | + |
| 69 | +View the file structure along with the code |
| 70 | + |
| 71 | + |
| 72 | + |
| 73 | +## How you should wrap the \_app js file |
| 74 | + |
| 75 | +Screenshot for understanding the file structure along with the code. |
| 76 | + |
| 77 | + |
| 78 | + |
| 79 | +## External API call & NEXT RUN BUILD |
| 80 | + |
| 81 | +I tried to add some external API call to see the hydration and rehydration process. A look into the SSG, Static & SSR rendering of the pages in this boilerplate. Seems good to me. |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | +## Contributing |
| 86 | + |
| 87 | +Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. |
| 88 | + |
| 89 | +Please make sure to update the tests as appropriate. |
| 90 | + |
| 91 | +## License |
| 92 | + |
| 93 | +[MIT](https://choosealicense.com/licenses/mit/) |
0 commit comments