I am using a free e-commerce API for data fetching and my getProducts
action is working in products.jsx. When I console.log(response)
this is working but I cant use useSelector
for fetching data from products.jsx.
I think my extraReducers
is not working cause I can't fetch data from products.
home.jsx
import { useDispatch, useSelector } from "react-redux";
import { useEffect, useState } from "react";
import { getProducts } from "../redux/products";
import Card from "../components/card";
function home() {
const dispatch = useDispatch();
const data = useSelector();
console.log("data");
// const [arr, setArr] = useState([]);
// console.log(arr);
// useEffect(async () => {
// const response = await dispatch(getProducts());
// setArr(response.payload.data);
// }, []);
useEffect(() => {
dispatch(getProducts());
}, [dispatch]);
return (
<div className="home">
{/* {arr.map((data) => {
return (
<>
<Card
title={data.title}
price={data.price}
img={data.images[0]}
></Card>
</>
);
})} */}
</div>
);
}
export default home;
products.jsx
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
export const getProducts = createAsyncThunk("getProducts", async () => {
const response = await axios.get("https://api.escuelajs.co/api/v1/products");
return response;
});
const initialState = {
products: [],
};
export const productsSlice = createSlice({
name: "counter",
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(getProducts.fulfilled, (state, action) => {
state.products = action.payload;
});
},
});
export const {} = productsSlice.actions;
export default productsSlice.reducer;
I implemented a second way for solving problem (you can see on home.jsx) but I want to use the useSelector
hook.
You have failed to pass a selector function to the useSelector
hook to actually select the products state that is updated.
const data = useSelector(); // <-- missing selector function!
Assuming you have created the store as follows:
import { configureStore, combineReducers } from '@reduxjs/toolkit';
import productsReducer from '../path/to/productsSlice';
// ... other imports ...
const rootReducer = combineReducers({
// ... other reducers
// matching slice name property, i.e. "counter", is a convention,
// but can be any valid Javascript identifier
counter: productsReducer,
});
const store = configureStore({
reducer: rootReducer,
});
Then the products "data" you are selecting is state.counter.products
.
const data = useSelector(state => state.counter.products);
It's common to not rename the selected values to something else which can cause confusion.
Examples:
const products = useSelector(state => state.counter.products);
or
const { products } = useSelector(state => state.counter);