skip to Main Content

I created a product reducer, product action, and home file along with constants file (mainly to name and store the type of the action). In Home I was trying to get the products from the backend that is already working.

I used dispatch and useSelector hooks for that function.

While I am using useSelector hook in the Home I am getting data as undefined. However when I checked by console logging in the action and the product file there the data is present.

I don’t know why this error is happening.

Home.js

import React, { Fragment, useEffect } from 'react'
import Loader from "../layout/Loader/Loader";
import MetaData from "../layout/MetaData.js";
import ProductCard from './ProductCard.js';
import { CgMouse } from "react-icons/cg";
import "./Home.css";
import { clearErrors, getProduct } from "../../actions/productAction";
import { useSelector, useDispatch } from "react-redux";

const product = {
  name: "Blue Tshirt",
  images: [{ url: "https://i.ibb.co/DRST11n/1.webp" }],
  price: "$3000",
  _id: "aditya",
};

const Home = () => {
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getProduct())
  }, [dispatch]);
 
  const data = useSelector((state) => state.products);
  console.log(data);

  // const { loading, error, products } = useSelector((state) => state.products);

  return (
    <div>
      {/* <Fragment>
        {loading ? (
          <Loader />
        ) : ( */}
          <Fragment>
            <MetaData title="ECOMMERCE" />
            <div className="banner">
              <p>WELCOME TO ECOMMERCE</p>
              <h1>FIND AMAZING PRODUCTS BELOW</h1>
              <a href="#container">
                <button>
                  Scroll<CgMouse />
                </button>
              </a>
            </div>
            <h2 className="homeHeading">Featured Products</h2>
            <div className="container" id="container">
              {/* {products && products.map((product)=>( */}
                <ProductCard key={product._id} product={product}/>
              {/* ))} */}
            </div>
          </Fragment>
        {/* )} */}
      {/* </Fragment> */}
    </div>
  )
}

export default Home

ProductReducer.js

import {
  ALL_PRODUCT_FAIL,
  ALL_PRODUCT_REQUEST,
  ALL_PRODUCT_SUCCESS,
  CLEAR_ERRORS,
} from "../constants/productContants";

export const productReducer = (state = { products: [] }, action ) => {
  // console.log(action.payload);
  switch(action.type){
    case ALL_PRODUCT_REQUEST:
      return {
        loading: true,
        product: [],
      };

    case ALL_PRODUCT_SUCCESS:
      let obj = {
        loading: false,
        products: action.payload.products,
        productsCount: action.payload.productsCount,
        resultPerPage: action.payload.resultPerPage,
        filteredProductsCount: action.payload.filteredProductsCount,
      };
      // console.log(obj);
      return obj;

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

    case CLEAR_ERRORS:
      return {
        ...state,
        error: null,
      };

    default:
      return state;
  }
};

productActions.js

import axios from "axios";

import {
  ALL_PRODUCT_FAIL,
  ALL_PRODUCT_REQUEST,
  ALL_PRODUCT_SUCCESS,
  CLEAR_ERRORS,
} from "../constants/productContants";

// get all the products 

export const getProduct = () => async (dispatch) => {
  try {
    dispatch({type:ALL_PRODUCT_REQUEST});
        
    const {data} = await axios.get("/api/v1/products");

    dispatch({
      type: ALL_PRODUCT_SUCCESS,
      payload: data,
    });
  } catch(error) {
    dispatch({
      type: ALL_PRODUCT_FAIL,
      payload: error.response.data.message,
    });
  };
}

Store.js

import { configureStore } from '@reduxjs/toolkit';
import { combineReducers } from "redux";
import { productReducer } from './reducers/productReducer';
import thunk from "redux-thunk";

const reducers = combineReducers({
  product: productReducer,
});

let initalState = {};

const store = configureStore({
  reducer: reducers,
  initalState
});

export default store;

I was trying to fetch the data from backend and was using useSelector() and useDispatch() hook. The data is being fetched from the backend however while using useSelector() I am getting that the data is undefined and I don’t understand why this is happening.

2

Answers


  1. const reducers = combineReducers({
      product: productReducer,
    });
    

    state.product is the state the productReducer provides, so if you are trying to access the products array of the productReducer then it should be state.product.products.

    const products = useSelector((state) => state.product.products);
    

    or if you use object destructuring assignment

    const { products } = useSelector((state) => state.product);
    

    Alternatively, if this is the only state you could pass productReducer directly to the store as the sole reducer, then state.products would be correct.

    const store = configureStore({
      reducer: productReducer,
      initalState
    });
    
    const products = useSelector((state) => state.products);
    
    Login or Signup to reply.
  2. Hi There is typo const data = useSelector((state)=>state.product);
    you can also write like this: const {loading,error,products} = useSelector((state)=>state.product);

    your reducers name is product not products (typo Here)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search