What is the process of triggering an action from within getInitialProps?

I've been struggling to integrate Redux into a Next.js app, particularly when trying to use the dispatch function within getInitialProps. For some reason, the store keeps returning as undefined and I can't seem to pinpoint the issue. I've followed the instructions on the next-redux-wrapper GitHub page, but something seems to be going wrong along the way. I know the code is functional - when I used axios to directly fetch the artPieces, it worked perfectly. However, my goal is to utilize Redux instead. The transition I'm making involves transforming a React/Express.js app into a Next.js app where I plan to rely on an API for essential server operations needed for a small blog application.

Here's a snippet from my store.js:

import { createStore } from 'redux';
import { createWrapper, HYDRATE } from 'next-redux-wrapper';

// reducer implementation
const reducer = (state = { tick: 'init' }, action) => {
    switch (action.type) {
        case HYDRATE:
            return { ...state, ...action.payload };
        case 'TICK':
            return { ...state, tick: action.payload };
        default:
            return state;
    }
}; 

// makeStore function definition  
const makeStore = (context) => createStore(reducer);

// exporting an assembled wrapper
export const wrapper = createWrapper(makeStore, { debug: true });

Next, let's look at the _app.js:

import './styles/globals.css';
import { wrapper } from '../store';

function MyApp({ Component, pageProps }) {
    return <Component {...pageProps} />;
}

export default wrapper.withRedux(MyApp);

Lastly, this is where the problem arises - attempting to call the dispatch function on the context within a sub component of _app.js:

import React from 'react';
import { ArtPiecesContainer } from './../components/ArtPiecesContainer';
import { useDispatch } from 'react-redux';
import axios from 'axios';
import { getArtPieces } from '../reducers';

const Art = ({ data, error }) => {
    return (
        <>
            <ArtPiecesContainer artPieces={data} />
        </>
    );
};

export default Art;

Art.getInitialProps = async ({ ctx }) => {
    await ctx.dispatch(getArtPieces());

    console.log('DATA FROM GETARTPIECES', data);

    return { data: ctx.getState() };
};

Answer №1

To make this work, it is recommended to use

"next-redux-wrapper": "^7.0.5"

_app.js

import { wrapper } from '../store'
import React from 'react';
import App from 'next/app';

class MyApp extends App {
  static getInitialProps = wrapper.getInitialAppProps(store => async ({Component, ctx}) => {
    return {
      pageProps: {
        // Call page-level getInitialProps
        // DON'T FORGET TO PROVIDE STORE TO PAGE
        ...(Component.getInitialProps ? await Component.getInitialProps({...ctx, store}) : {}),
        // Some custom thing for all pages
        pathname: ctx.pathname,
      },
    };

  });

  render() {
    const {Component, pageProps} = this.props;

    return (
      <Component {...pageProps} />
    );
  }
}

export default wrapper.withRedux(MyApp);

and Index.js

import { useEffect } from 'react'
import { useDispatch } from 'react-redux'
import { END } from 'redux-saga'
import { wrapper } from '../store'
import { loadData, startClock, tickClock } from '../actions'
import Page from '../components/page'

const Index = () => {
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(startClock())
  }, [dispatch])

  return <Page title="Index Page" linkTo="/other" NavigateTo="Other Page" />
}

Index.getInitialProps = wrapper.getInitialPageProps(store => async (props) => {
  store.dispatch(tickClock(false))

  if (!store.getState().placeholderData) {
    store.dispatch(loadData())
    store.dispatch(END)
  }

  await store.sagaTask.toPromise()
});


export default Index

You can find the remaining code in nextjs/examples/with-redux-saga, however, please note that they are currently using an older version of next-redux-wrapper (version 6).

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

Exploring the plane intersection within a 3D object using Three.js

I attempted to create an animation using Three.js to display the intersection plane on a 3D object with the following code snippet: import React, { useRef, useEffect, useState } from 'react'; import * as THREE from 'three'; export cons ...

How to Efficiently Remove Array Elements by Index in Typescript

What is the best way to remove an item by its index using Typescript? For example: let myArray = ['apple', 'banana', 'cherry', 'date']; // How can I delete the item at index 2? ...

Difficulty arises when applying hover effects to animations using callbacks

Currently facing an issue with the hover event in jQuery. There are two side-by-side containers with hover events on both. When hovering, a div containing additional information slides up into view and slides back down when the hover ends. The concept is ...

What is the best method for assigning a default value to the file input tag in HTML?

Can anyone help me with this code snippet? <input name="GG" type="file" value="< ?php echo $data['image'] ?>"> I was trying to set a default value in the form edit, but it seems to not be working. Does anyone know how to set a defau ...

How to send a DOM element's value to an AJAX request using HTML.PagedList parameters

As I delve into learning ajax requests, I find myself questioning if I am on the right track. Currently, I have a page that incorporates pagination, sorting, and searching functionalities. My goal is to implement these features using ajax to avoid reloadin ...

Avoid re-rendering the template in Vue 3 with pinia when changing state values

I am utilizing Vue3 and Pinia for state management. Here is an excerpt from my Pinia file: export const useCounterStore = defineStore ({ id: 'statusData', state: () => ({ test1: 25, test2: 75 }) }) As for the template I am us ...

Vue JS: Extracting both the unique ID and value from an array of input simultaneously

I am new to Vue and currently exploring its capabilities. I am experimenting with the Element UI for Vue's user interface. Specifically, I am working with the Input Number Component, to manage an array of data. Let's assume my data is structured ...

Unable to create account using PHP

Every time I attempt to create an account, the data I receive is always problematic. The username must be between 3 and 15 characters I find it frustrating that the account creation never goes through successfully. What baffles me even more is that af ...

Issue with MUI Autocomplete not showing selected name on initial option selection

I encountered a strange issue with the Autocomplete component from Material UI. Here is the code snippet in question: const [isContactListInitialised, setContactListInitialised] = useState(false); const toggleContactListInitialized = () => { setContactL ...

Learn how to show image information in a separate div by clicking on the image using jQuery

Is there a way to show or hide information of an image in a separate div by clicking on the image itself? $(document).ready(function () { $(".cell").click(function () { $(this).find("span").toggle("slow"); }) }); <div class="cell"> ...

Reactivity in Vue.js powered by ES6 classes

I am attempting to create a computed property in Vue.js that is associated with an ES6 class. Here is an example of my Vue instance setup: ... props: ['customClass'], computed: { localClass: { get() { return this.custom ...

Navigating React Redux Pages Using React Router

At the moment, I am exploring the possibility of creating an application using React and Redux. Most examples I've come across make use of React Router, so I'm curious about its purpose. My application will consist of multiple pages (at least 20 ...

Update breadcrumbs dynamically by clicking on each horizontal panel

I've been dealing with a problem for the past 24 hours. I want to implement a horizontal accordion with breadcrumbs on a webpage. How can I achieve this dynamically, so that when a user clicks on any link in the accordion, the breadcrumbs update simul ...

Filtering data in Laravel can be efficiently achieved by utilizing Laravel's ORM hasmany feature in conjunction with Vue

Hey there, I'm currently working with Laravel ORM and Vue 2. I've encountered some issues with analyzing Json data. Here's my Laravel ORM code: $banner = Banner::with('banner_img')->get(); return response()->json($banner); ...

Creating a Map Using HTML and JavaScript

My current project involves creating a simple map that can be moved with mouse drag functionality, featuring images such as islands. I have successfully retrieved the mouse position by declaring variables posX and e.clientX, as well as for e.clientY. Howe ...

The only thing visible on my project is the homepage, void of any buttons or additional pages

After completing this school project, I believed that everything was done correctly. However, as I faced issues with the code, I decided to seek help and share my app.js and bin section for clarification. Starting it with npm on the localhost as shown in ...

What steps can you take to resolve the "TypeError: Cannot read property 'id' of undefined" issue?

I have been developing an app that involves using databases to add items for users based on their user ID, which is their username. However, whenever I attempt to add an item, I encounter an error that I can't seem to troubleshoot. The error message r ...

What is the best way to confirm that a SQL pool has been successfully created in an Express JS?

Currently, I am in the process of developing a restful API using mysql and expressjs. Below is an example showcasing how I send requests to my database: server.js: const express = require('express'), bodyParser = require('body-parser&ap ...

What is the best way to format specific text as bold within an input text field?

I am attempting to make certain text bold within an input text field. However, I'm uncertain about how to achieve this because HTML code is not recognized inside a text field. Therefore, using <b> will not be effective. Is there a way to bold sp ...

Tips for navigating libraries with Google CAJA

Is there a way to configure Google Caja to allow specific libraries to work without being sanitized? I have my own CAJA server and an application based on NodeJS. I'm providing users with code that is mostly related to charts and graphs, but certain ...