1

I am new to Next.js, So I follow some tutorials for Redux integration in Next.js. All is working fine but whenever I switch between pages, each time API make a call, and Redux lost its stored value.

The basic function is like this. Whenever a user loads a website an API call will fetch category data from the server and save that data in reducer[categoryReducer], then the user can navigate to any page and category data will fetched from the reducer. But in my case, it hits again and again

Full Code:

// Action Call

import * as Constants from '../../constant/constant';
import * as t from '../types';
import axios from 'axios';

export const loadCategoryApi = (type) => dispatch => {
    axios.post(Constants.getCategories,type)
    .then(function (response) {
        console.log(response);
        if(response && response.data && response.data.status==="200"){
            dispatch({
                type: t.LOAD_CATEGORY,
                value: type
            });
        }
        else if(response && response.data && response.data.status==="404"){
            alert('Someting went wrong');
        }
    })    
}
// Reducer File

import * as t from '../types';

const initialState = {
    doc:null
}

const CategoryReducer = (state = initialState, action) =>{
    console.log('reducer action', action.type);
    switch (action.type){
        case t.LOAD_CATEGORY:
            console.log('slots actions',action);
             return({...state, doc:action.value})

        default:
            return state;    
    }
}

export default CategoryReducer;
// Store file
import { createStore, applyMiddleware, compose } from "redux"
import thunk from "redux-thunk"
import { createWrapper } from "next-redux-wrapper"
import rootReducer from "./reducers/rootReducer"

const middleware = [thunk]

const makeStore = () => createStore(rootReducer, compose(applyMiddleware(...middleware)))

export const wrapper = createWrapper(makeStore);
// rootReducer

import { combineReducers } from "redux"
import CategoryReducer from "./CategoryReducer";

const rootReducer = combineReducers({
    CategoryReducer: CategoryReducer
})

export default rootReducer;
// _app.js

import React from "react"
import { wrapper } from "../redux/store"
import Layout from '../components/Layout';
import '../styles/globals.css'


const MyApp = ({ Component, pageProps }) =>(
    <Layout>
      <Component {...pageProps} />
    </Layout>
);

export default wrapper.withRedux(MyApp);
// Uses
import React, { useState, useEffect } from 'react';
import {connect} from "react-redux";
import {loadCategoryApi} from "../redux/actions/CategoryAction";

function navbar(props){
  const { loadCategory, loadCategoryApi } = props;
  useEffect(() => {
        if(loadCategory===null){
            console.log('navbar loading funciton');
            loadCategoryFunation();
        }
    }, []);
    
     const loadCategoryFunation = () =>{
        var json = {
            type : 'main'
        };
        loadCategoryApi(json);
    }
  
}


const mapStateToProps = state => {
    return { loadCategory: state.CategoryReducer.doc }
}

const mapDispatchToProps = {
    loadCategoryApi
}
  
export default connect(mapStateToProps, mapDispatchToProps)(Navbar)

What I am doing wrong?

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Pooja
  • 543
  • 7
  • 26

1 Answers1

0

You have to create main reducer to handle the hydration. I explained this hydration process here.

In the file that you created the store, write main reducer

import reducers from "./reducers/reducers";

const reducer = (state, action) => {
  // hydration is a process of filling an object with some data
  // this is called when server side request happens
  if (action.type === HYDRATE) {
    const nextState = {
      ...state,
      ...action.payload,
    };
    return nextState;
  } else {
    // whenever we deal with static rendering or client side rendering, this will be the case
    // reducers is the combinedReducers
    return reducers(state, action);
  }
};

then pass this reducer to the store

Yilmaz
  • 35,338
  • 10
  • 157
  • 202