Search code examples
reactjsreduxreact-reduxaxios

Destructured contents of Redux state returns an empty array but there is data after I fetch data with axios


I am creating an e-commerce front-end that I have its Server posted in Heroku created with nodejs. I am trying to use Redux to implement every operation on the website. I tried to call all the list of products in the database using the redux method but when console.log the products after-action creators I get an empty array

My Store Code

import {createStore, combineReducers, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import {composeWithDevTools} from 'redux-devtools-extension';
import { productsListReducer} from './reducers/productsReducer';


const reducer = combineReducers({

     productList:productsListReducer,
});

const initialState = {};

const middleware = [thunk];

const store = createStore(
    reducer,
    initialState,
    composeWithDevTools(applyMiddleware(...middleware))
);

export default store;

My Constants For Products

export const PRODUCTS_LIST_REQUEST = "PRODUCTS_LIST_REQUEST";
export const PRODUCTS_LIST_SUCCESS = "PRODUCTS_LIST_SUCCESS";
export const PRODUCTS_LIST_FAIL = "PRODUCTS_LIST_FAIL";

My ProductsReducer Code

import {
  PRODUCTS_LIST_FAIL,
  PRODUCTS_LIST_REQUEST,
  PRODUCTS_LIST_SUCCESS,
} from "../constants/productConstants";

export const productsListReducer = (state = { products:[]}, action) => {
  
  switch (action.type) {
    case PRODUCTS_LIST_REQUEST:
      return {
        loading: true,
      };

    case PRODUCTS_LIST_SUCCESS:
      return {
        loading: false,
        products: action.payload,
      };

    case PRODUCTS_LIST_FAIL:
      return {
        loading: false,
        error: action.payload,
      };

    default:
      return state;
  }
};

My Action Creator Code

import axios from "axios";
import {
  PRODUCTS_LIST_FAIL,
  PRODUCTS_LIST_REQUEST,
  PRODUCTS_LIST_SUCCESS,
} from "../constants/productConstants";

export const Products = () => async (dispatch) => {
  try {
    dispatch({
      type: PRODUCTS_LIST_REQUEST,
    });

    const headers = {
      "Content-Type":"application/json",
    };
    const url = `${process.env.REACT_APP_SERVER_URL}api/products`;

    const { data } = await axios.get(url, { headers });

    dispatch({
      type: PRODUCTS_LIST_SUCCESS,
      payload: data,
    });
    
  } catch (error) {
    const message =
      error.response && error.response.data.message
        ? error.response.data.message
        : error.message;

    dispatch({
      type: PRODUCTS_LIST_FAIL,
      payload: message,
    });
  }
};

How I am Trying to get The Reducer data in-home Page

import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Products } from "../../actions/productsActions";
import SideBar from "../Home/SideBar";
import SingleProduct from "../Home/SingleProduct";

const Home = () => {

const dispatch = useDispatch();

const productList = useSelector((state) => state.productList);

const { products, error, loading } = productList

console.log("products", products)

useEffect(() => {
    dispatch(Products);
},[dispatch])


  return (
    <div className ='home'>
      <SideBar />
      <div className="productConatiner">
        {
            products.map((product) => {
              return <span>{product?.title}</span>
            })
        };
      </div>
    </div>
  );
};

export default Home;

Solution

  • The problem is that you're not actually dispatching an action. You should write

    useEffect(() => {
      dispatch(Products());
    },[dispatch])
    

    instead of

    useEffect(() => {
      dispatch(Products);
    },[dispatch])