cannot read property 'dispatch' of undefined in nextjs

Viewed 1056

I'm stuck with the dispatch function where it cannot be read. I want to pull data from store.js file into index.js to display it. I'm currently experimenting Redux for my web project that has huge data.

I'm not really familiar with Redux. Is there any other way to catch a huge data? And what did I go wrong with my code?

//This is the store.js file

import { createWrapper } from 'next-redux-wrapper';
import { createStore } from 'redux';
import data from './pages/API/data.json';

//initial state
const startState = {
    cards: []
};

//Actions
export const initialCards = () => {
    return {
        type: 'INITIALCARDS',
        cards: data
    }
};

export const addItem = (item) => {
    return {
        type: 'ADD',
        item
    }
};

//create a reducer

export const reducer = (state = initialState, action) => {
    switch(action.type){
        case 'INITIALCARDS':
            return {
                cards: action.cards,
            }
        case 'ADD':
            return {
                ...state,
                cards: [...state.cards, action.item],
            }
        default: return state
    }
}

//create store

const store = (initialState = startState) => {
    return createStore(reducer, initialState);
};

export const initStore = createWrapper(store);

//This is the index.js file

import React from 'react';
import styles from './index.module.css';
import Card from './Card';
import { initStore, initialCards, addItem } from '../store';

class Index extends React.Component {
    static async getInitialProps ({ store }){
        return store.dispatch(initialCards());
    }
    render (){
        return (
            <div className={styles.app}>
                <header className={styles.header}>
                    <img src="/logo.png" className={styles.logo} alt="logo" />
                </header>
                <div className={styles.grid}>
                    {
                        this.props.cards.map((card) => (
                            <Card key={card.id} />
                        ))
                    }
                </div>
                {/*<button onClick={() => dispatch(addItem(item))}></button>*/}
            </div>
        )
    }
};

export default initStore.withRedux(Index);

3 Answers

I modified the code little bit and got the desired results.

use functional component and useDispatch method from redux.

Imports needed:

import { useDispatch } from 'react-redux';

Component:

const Index = () => {

const dispatch = useDispatch();
const {cards} = dispatch(initialCards());
return (
    <div className={styles.app}>
        <header className={styles.header}>
            <img src="/logo.png"
                className={styles.logo} alt="logo"
            />
        </header>
        <div className={styles.grid}>
        {
            cards.map((card) => (
                <Card key={card.id} />
            ))
        }
        </div>
        {/* <button onClick={() => dispatch(addItem())}></button> */}
    </div>
)};
export default initStore.withRedux(Index);

I was getting the same error so used older version of "next-redux-wrapper"

Was using,

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

Then, reverted to older versions

"next-redux-wrapper": "^6.0.2"

And fixed my problem

This issue is due to the upgradation of next-redux-wrapper from version 6 to 7. And hence all the initialProp methods should be wrapped inside their proper store wrappers.

class Page extends Component{

     public static getInitialProps = wrapper.getInitialPageProps(store => () => { ... });
     render() {
       // stuff
     }
}
export default Page;

Hence, modifying the function of getInitialProps in the index.js file to,

static getInitialProps = initStore.getInitialAppProps((store) => async () => {
return store.dispatch(initialCards());
});

worked for me.

Related