├── public └── favicon.ico ├── src ├── store │ ├── actions │ │ ├── actionTypes.js │ │ └── counter.js │ ├── reducer │ │ ├── index.js │ │ └── counter.js │ └── index.js └── pages │ ├── _app.js │ └── index.js ├── README.md ├── package.json ├── .gitignore └── components └── nav.js /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VladymyrPylypchatin/nextjs-redux-boilerplate/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/store/actions/actionTypes.js: -------------------------------------------------------------------------------- 1 | export const COUNTER_INCRIMENT = 'COUNTER_INCRIMENT'; //Will add one to counter 2 | export const COUNTER_DECRIMENT = 'COUNTER_DECRIMENT'; //Will subscruct one from counter 3 | -------------------------------------------------------------------------------- /src/store/reducer/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import counterReducer from './counter'; 3 | 4 | const rootReducer = combineReducers({ 5 | counter: counterReducer, 6 | }); 7 | 8 | export default rootReducer; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nextjs-redux-boilerplate 2 | An example of the Next.js Project using Redux, Redux-thunk and Redux Debuger 3 | 4 | To run the project folow the instructions 5 | 6 | `npm i` 7 | 8 | `npm run dev` 9 | 10 | Then open in the browser `http:/localhost:3000` 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-next-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "next": "9.2.1", 12 | "react": "16.12.0", 13 | "react-dom": "16.12.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | .env* 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /src/pages/_app.js: -------------------------------------------------------------------------------- 1 | import withRedux from 'next-redux-wrapper'; 2 | import { Provider } from 'react-redux'; 3 | import initStore from '../store'; 4 | 5 | 6 | function MyApp({ Component, pageProps, store, ...rest }) { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | 14 | 15 | export default withRedux(initStore)(MyApp); -------------------------------------------------------------------------------- /src/store/actions/counter.js: -------------------------------------------------------------------------------- 1 | import * as actionTypes from './actionTypes'; 2 | 3 | export const counterIncriment = () => ({ type: actionTypes.counterIncriment }); 4 | export const counterDecriment = () => ({ type: actionTypes.counterDecriment }); 5 | 6 | //Example of the async actoins with redux-tunk 7 | export const counterIncrimentAsync = () => (dispatch) => { 8 | setTimeout(() => { 9 | dispatch(counterIncriment); 10 | }, 2000); 11 | }; -------------------------------------------------------------------------------- /src/store/reducer/counter.js: -------------------------------------------------------------------------------- 1 | import * as actionTypes from '../actions/actionTypes'; 2 | const initialState = { 3 | count: 0, 4 | }; //Initial state of the counter 5 | 6 | const reducer = (state = initialState, action) => { 7 | switch (action.type) { 8 | case actionTypes.COUNTER_INCRIMENT: 9 | return { 10 | count: state.count + 1, 11 | }; 12 | 13 | case actionTypes.COUNTER_DECRIMENT: 14 | return { 15 | count: state.count - 1, 16 | }; 17 | 18 | default: return state; 19 | } 20 | }; 21 | 22 | export default reducer; -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import rootReducer from './reducer/index'; 2 | import thunk from 'redux-thunk'; 3 | import { createStore, applyMiddleware, compose } from 'redux'; 4 | 5 | const initStore = (initialState, options) => { 6 | let composeEnhancers = compose; 7 | 8 | //Check if function running on the sever or client 9 | if (!options.isServer) { 10 | //Setup Redux Debuger 11 | composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; 12 | } 13 | 14 | 15 | 16 | const store = createStore(rootReducer, initialState, composeEnhancers( 17 | applyMiddleware(thunk) //Applying redux-thunk middleware 18 | )); 19 | 20 | return store; 21 | }; 22 | 23 | 24 | export default initStore; -------------------------------------------------------------------------------- /components/nav.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Link from 'next/link' 3 | 4 | const links = [ 5 | { href: 'https://zeit.co/now', label: 'ZEIT' }, 6 | { href: 'https://github.com/zeit/next.js', label: 'GitHub' }, 7 | ].map(link => ({ 8 | ...link, 9 | key: `nav-link-${link.href}-${link.label}`, 10 | })) 11 | 12 | const Nav = () => ( 13 | 54 | ) 55 | 56 | export default Nav 57 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Head from 'next/head' 3 | import Nav from '../components/nav' 4 | 5 | const Home = () => ( 6 |
7 | 8 | Home 9 | 10 | 11 | 12 |
86 | ) 87 | 88 | export default Home 89 | --------------------------------------------------------------------------------