Setting up redux with Next.js: a step-by-step guide

After setting up redux in this manner, everything is functioning properly.

The _app.js file has been reorganized as follows :

import App from 'next/app';
import { Provider } from 'react-redux';
import withRedux from 'next-redux-wrapper';
import store from '../redux/store';
import React from 'react';

class MyApp extends App {
    static async getInitialProps({ Component, ctx }) {
        const appProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};

        console.log(appProps);

        return {
            appProps: appProps
        };
    }
    render() {
        const { Component, appProps } = this.props;
        return (
            <Provider store={store}>
                <Component {...appProps} />
            </Provider>
        );
    }
}

const makeStore = () => store;

export default withRedux(makeStore)(MyApp);

This is the index.js file which has been linked to redux :

import { connect } from 'react-redux';
import { callAction } from '../redux/actions/main';

const Index = (props) => {
    console.log(props);
    return (
        <div>
            State of Index js <button onClick={() => props.callAction()}>Call action</button>
        </div>
    );
};

const mapStateToProps = (state) => ({
    name: state.main.name
});

const mapDispatchToProps = {
    callAction: callAction
};

export default connect(mapStateToProps, mapDispatchToProps)(Index);

This is the rootReducer file which only contains one reducer named main :

import { main } from './main';
import { combineReducers } from 'redux';

export const rootReducer = combineReducers({
    main: main
});

And here is the store.js file :

import { createStore } from 'redux';
import { rootReducer } from './reducers/rootReducer';

const store = createStore(rootReducer);

export default store;

Everything is functioning correctly but there is a warning displayed in the console saying:

/!\ You are using legacy implementaion. Please update your code: use createWrapper() and wrapper.withRedux().

What specific changes need to be made to which files in order to resolve the legacy implementation warning?

Answer №1

To resolve the warning, I made changes to how I access redux states and actions in my index.js file and how I pass them in my _app.js file using createWrapper and withRedux:

_app.js

import App from 'next/app';
import store from '../redux/store';
import { Provider } from 'react-redux';
import { createWrapper } from 'next-redux-wrapper';

class MyApp extends App {
    render() {
        const { Component, pageProps } = this.props;
        return (
            <Provider store={store}>
                <Component {...pageProps} />
            </Provider>
        );
    }
}
const makeStore = () => store;
const wrapper = createWrapper(makeStore);

export default wrapper.withRedux(MyApp);

index.js

import { callAction } from '../redux/action';
import { connect } from 'react-redux';

const Index = (props) => {
    return (
        <div>
            hey {props.name}
            <br />
            <button onClick={() => props.callAction()}>Call action</button>
        </div>
    );
};

const mapState = (state) => {
    return {
        name: state.name
    };
};

const mapDis = (dispatch) => {
    return {
        callAction: () => dispatch(callAction())
    };
};

export default connect(mapState, mapDis)(Index);

Answer №2

This solution was effective for me when working on TypeScript:

================== _app.tsx ================== 
import type { AppProps } from 'next/app'
import { Provider } from 'react-redux';
import { createWrapper } from 'next-redux-wrapper';
import { store } from '../redux/store';

function MyApp({ Component, pageProps }: AppProps & { Component: { layout: any }}) {
  const Layout = Component.layout || (({ children }) => <>{children}</>);
  return (
    <Provider store={store}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </Provider>
  );
}

MyApp.getInitialProps = async ({ Component, router, ctx }) => {
  const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
  return { pageProps };
}

const makeStore = () => store;
const wrapper = createWrapper(makeStore);

export default wrapper.withRedux(MyApp);
================== store.tsx ================== 
import { applyMiddleware, createStore } from 'redux';
import thunkMiddleware from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';

import { rootReducer } from '../reducers';

export const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(thunkMiddleware)),
);

export type AppDispatch = typeof store.dispatch;
================== reducers.tsx ================== 
import * as redux from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { Action } from 'typesafe-actions';

import user from './user';

export const rootReducer = redux.combineReducers({
  user,
});

export type AppThunkDispatch = ThunkDispatch<RootState, void, Action>;
export type RootState = ReturnType<typeof rootReducer>;

================== onereducer.tsx ================== 
import { HYDRATE } from "next-redux-wrapper";
import { Reducer } from 'redux';
import { ActionType } from 'typesafe-actions';
import { USER_ACTIONS } from '../../actions/types';
import { IUserData } from './types';

const userState: IUserData = {
  _id: '',
  email: '',
  password: '',
  role: '',
};

const userReducer: Reducer<IUserData, ActionType<any>> = (
  state = userState,
  action,
) => {
  switch (action.type) {
    case HYDRATE:
      return { ...state, ...action.payload.userData };
    case USER_ACTIONS.SET_USER_DATA:
      return { ...state, ...action.payload.userData };
    default:
      return { ...state };
  }
};

export default userReducer;

Note: This is an ongoing project but the current solution is functioning well!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to automatically increase a value by clicking on it?

Check out this code snippet I'm working with: let funds = document.createElement('funds') funds.style.color = 'green' funds.style.textAlign = 'center' funds.style.fontSize = '50px' funds.style.backgroundCol ...

Is there a way to transform this Json array into a format that JQuery can interpret easily?

Having a bit of trouble with this issue. I'm not entirely sure how to get it working correctly. According to Firebug, the Json object (or possibly array) from my ajax request appears as follows: { "jsonResult": "[ {\"OrderInList\":1}, ...

Utilize SectionList and a custom header view on Y to achieve a translation effect that creates a visually appealing empty space as

Hello everyone, I am fairly new to React Native and the Animated API. My goal is to create a simple parallax header and an Animated SectionList similar to this demonstration. https://i.stack.imgur.com/R2GBP.gif Below is a snippet of my code: export defa ...

Encountering difficulties with updating customer information in postgreSQL

I am attempting to perform CRUD operations using pg-promises and stored procedures in PostgreSQL. Here is my code: controller.js: const db = require("./../index.js"); exports.getAllData = async (req, res, next) => { try { const data = ...

The information returned to the callback function in Angular comes back null

In my Node.js application, I have set up an endpoint like this: usersRoute.get('/get', function(req, res) { //If no date was passed in - just use today's date var date = req.query.date || dateFormat(new Date(), 'yyyy-mm-dd&ap ...

When scrolling, use the .scrollTop() function which includes a conditional statement that

As a newcomer to jQuery, I've been making progress but have hit a roadblock with this code: $(window).scroll(function(){ var $header = $('#header'); var $st = $(this).scrollTop(); console.log($st); if ($st < 250) { ...

clearing all input fields upon submission in React Native

I need help resolving an error that occurs when I try to clear text input fields on a button press. Instead of clearing the fields, it throws an undefined error because I am trying to set the value as {this.state.inputTextValue} and then clear it using set ...

Switching Next.js route using pure JavaScript

Currently, I am facing a challenge in changing the route of a Next.js application using vanilla Javascript. In order for the code to be compatible with Chrome Dev Tools, I cannot dynamically change the route with Next.js and instead must find a solution us ...

What is the best way to send information from App.js to components?

In my project, I am working with App.js and a functional component called "uploadlist". The goal is to pass a 'custid' value from App.js to the uploadlist component. Here's what I have attempted: app.js: export default class App extends Com ...

Triggering Jquery event multiple times

I am using a jQuery datatable that gets populated with data from a database through an AJAX call when a user clicks on a load button. The data is displayed based on the date selected by the user in a datepicker. I have also added an export button to allow ...

A guide on achieving a dynamic color transition in Highcharts using data values

I am currently working on plotting a graph using high charts and I would like to change the color based on the flag values. I attempted this, however, only the points are changing based on the flag values and the line is not being colored accordingly. Be ...

The error message thrown is: "Unable to assign headers after they have already been sent to the client."

I've been attempting to make a GET request, but it keeps failing at the app.js res.json line. app.js app.use(function(err, req, res, next) { res.locals.message = err.message; res.locals.error = req.app.get("env") === "development" ? err : {}; ...

Unable to redirect Firebase Hosting root to a Cloud Function successfully

Currently I am utilizing Firebase Hosting along with a Firebase.json file that is configured to direct all traffic towards a cloud function (prerender) responsible for populating meta and og tags for SEO purposes. { "hosting": { "public": "dist/pr ...

Analyzing critical code paths for optimal performance

There is a function that accepts two arguments and an optional third argument. The function should return true if the first argument is greater than the second, false if not, unless the third argument is true, in which case it should return true if the fir ...

Assign Attribute to a Different Data Transfer Object

I have a query regarding my nestjs project - is it possible to assign a value Attribute to another Dto? Specifically, I'm looking to assign idData to the id in IsUniqueValidator. I attempted the following code but it resulted in 'undefined&apos ...

What is the best way to iterate over JSON data from an endpoint that contains multiple nested arrays using the .map() method?

Seeking to showcase weather API data from: () import Image from "next/image" interface Hour { time_epoch: number time: string temp_c: number temp_f: number is_day: number wind_mph: number wind_kph: number wind_deg ...

Flickering of image in JavaScript when mouse is hovered over and removed

I recently encountered an issue while attempting to create a mouseover effect that would display a larger image when hovering over a smaller default image. The problem arose when the larger image started flickering uncontrollably upon hover. Check out the ...

Unsynchronized AJAX POST requests fail to function effectively

I am encountering an issue with an AJAX call that I am using to log in a user. Here is the code: function loginUser() { var xmlhttp; if(window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest() ...

Why am I not receiving the expected feedback after submitting a request for a specific parameter in a Node.js and Express Router REST API?

Developed a Node module utilizing the Express router to facilitate the routes for the dishes REST API. Index.js file: const express = require('express'); const http = require('http'); const morgan = require('morgan'); const b ...

Creating a horizontal scroll effect using jQuery when the widths of the items are not

I am working on a jQuery gallery that showcases images in a horizontal layout. Below the images, there are "left" and "right" buttons which allow users to scroll through the pictures. There are many tutorials and plugins available for this type of function ...