Я создал редуктор продукта, действие продукта и домашний файл вместе с файлом констант (в основном для имени и хранения типа действия). В Home я пытался получить products из уже работающего бэкэнда.
Для этой функции я использовал хуки dispatch и useSelector.
Пока я использую крючок useSelector в Home, я получаю данные как неопределенные. Однако когда я проверил с помощью входа в консоль действие и файл продукта, данные присутствуют.
Я не знаю, почему происходит эта ошибка.
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.info(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
Продуктредуцер.js
import {
ALL_PRODUCT_FAIL,
ALL_PRODUCT_REQUEST,
ALL_PRODUCT_SUCCESS,
CLEAR_ERRORS,
} from "../constants/productContants";
export const productReducer = (state = { products: [] }, action ) => {
// console.info(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.info(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,
});
};
}
Магазин.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() я получаю, что данные не определены, и не понимаю, почему это происходит.
@PatrickMichaelsen Должно быть, прошло какое-то время. Компонент высшего порядка connect уже давно не является рекомендуемым способом подписки на компонент в магазине Redux. Хук useSelector — это то, как мы сегодня подписываемся на магазин или подключаемся к нему.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


const reducers = combineReducers({ product: productReducer, });
state.product — это состояние, которое productReducer обеспечивает, поэтому, если вы пытаетесь получить доступ к массиву productsproductReducer, то это должно быть state.product.products.
const products = useSelector((state) => state.product.products);
или если вы используете назначение деструктуризации объекта
const { products } = useSelector((state) => state.product);
Альтернативно, если это единственное состояние, которое вы можете передать productReducer непосредственно в хранилище в качестве единственного редуктора, то state.products будет правильным.
const store = configureStore({
reducer: productReducer,
initalState
});
const products = useSelector((state) => state.products);
const data = useSelector((state)=>state.product);
вы также можете написать так:
const {loading,error,products} = useSelector((state)=>state.product);
имя вашего редуктора — это продукт, а не продукты (здесь опечатка)
Я давно не работал с Redux, но разве вам не нужно подключать свой магазин к компоненту Home?