我创建了一个产品减速器、产品动作和主文件以及常量文件(主要用于命名和存储动作的类型).在Home中,我试图从已经正常工作的后端获得products.

我使用了dispatchuseSelector挂钩来实现该功能.

当我在Home中使用useSelector钩子时,我得到的数据是未定义的.但是,当我通过控制台登录操作和那里的产品文件进行判断时,数据已经存在.

我不知道为什么会发生这个错误.

家,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;

我试图从后端获取数据,并使用了useSelector()useDispatch()挂钩.数据是从后端获取的,然而,当使用useSelector()时,我发现数据是未定义的,我不明白为什么会发生这种情况.

推荐答案

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

state.productproductReducer提供的状态,所以如果您试图访问productReducerproducts数组,那么它应该是state.product.products.

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

或者如果您使用对象分解赋值

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

或者,如果这是唯一可以将productReducer作为唯一减速器直接传递给store 的状态,则state.products将是正确的.

const store = configureStore({
  reducer: productReducer,
  initalState
});
const products = useSelector((state) => state.products);

Javascript相关问答推荐

单击另一个按钮后启用按钮

有没有方法在Angular中的bowser选项卡之间移动HTML?

为什么新的Promises会在不需要的情况下被用来等待?

我可以在useState中调用函数并使用其数据吗

如何制作删除按钮以从列表中删除该项目所属的项目?

根据总价格对航班优惠数组进行排序并检索前五个结果- Angular HTTP请求

如何使用侧边滚动按钮具体滚动每4个格?

在React中获取数据后,如何避免不必要的组件闪现1秒?

我应该绑定不影响状态的函数吗?'

如何禁用附加图标点击的v—自动完成事件

你怎么看啦啦队的回应?

如何在 cypress 中使用静态嵌套循环

还原器未正确更新状态

使用ThreeJ渲染的形状具有抖动/模糊的边缘

Eval vs函数()返回语义

WP Bootstrap NavWaker:下拉菜单一次打开所有下拉菜单

元素字符串长度html

面对代码中的错误作为前端与后端的集成

传递方法VS泛型对象VS事件特定对象

使用Document.Evaluate() Select 一个包含撇号的HTML元素