javascriptreactjsreduxnext.jsnext-redux-wrapper

Using react redux with next.js


I try to use Redux with next.js starter project and I installed next-redux-wrapper on the project but I'm not sure where is the root file in this project.

I try to follow the tutorial shown on the next-redux-wrapper but had no success. Nothing change.

Please help me with how to add Redux to the project.

Regards.


Solution

  • Next.js uses the App component to initialize pages. You can override it and control the page initialization.

    Although this demo is for next.js it should work for nextjs-starter.

    install next-redux-wrapper:

    npm install --save next-redux-wrapper

    Add _app.js file to ./pages directory:

    // pages/_app.js
    import React from "react";
    import {createStore} from "redux";
    import {Provider} from "react-redux";
    import App, {Container} from "next/app";
    import withRedux from "next-redux-wrapper";
    
    const reducer = (state = {foo: ''}, action) => {
        switch (action.type) {
            case 'FOO':
                return {...state, foo: action.payload};
            default:
                return state
        }
    };
    
    /**
    * @param {object} initialState
    * @param {boolean} options.isServer indicates whether it is a server side or client side
    * @param {Request} options.req NodeJS Request object (not set when client applies initialState from server)
    * @param {Request} options.res NodeJS Request object (not set when client applies initialState from server)
    * @param {boolean} options.debug User-defined debug mode param
    * @param {string} options.storeKey This key will be used to preserve store in global namespace for safe HMR 
    */
    const makeStore = (initialState, options) => {
        return createStore(reducer, initialState);
    };
    
    class MyApp extends App {
    
        static async getInitialProps({Component, ctx}) {
    
            // we can dispatch from here too
            ctx.store.dispatch({type: 'FOO', payload: 'foo'});
    
            const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
    
            return {pageProps};
    
        }
    
        render() {
            const {Component, pageProps, store} = this.props;
            return (
                <Container>
                    <Provider store={store}>
                        <Component {...pageProps} />
                    </Provider>
                </Container>
            );
        }
    
    }
    
    export default withRedux(makeStore)(MyApp);
    

    And then, actual page components can be simply connected: This demo how to connect index.js in pages.

    import Link from "next/link";
    import React from "react";
    import {
      Container,
      Row,
      Col,
      Button,
      Jumbotron,
      ListGroup,
      ListGroupItem
    } from "reactstrap";
    import Page from "../components/page";
    import Layout from "../components/layout";
    
    import { connect } from "react-redux";
    
    class Default extends Page {
      static getInitialProps({ store, isServer, pathname, query }) {
        store.dispatch({ type: "FOO", payload: "foo" }); // component will be able to read from store's state when rendered
        return { custom: "custom" }; // you can pass some custom props to component from here
      }
      render() {
        return (
          <Layout>content...</Layout>
        );
      }
    }
    
    export default connect()(Default);
    

    Refer to the documentation for more information: next-redux-wrapper