I am new to React and currently following a fullstack tutorial using Django + ReactTS + Redux. The tutorial uses a slightly out of date method to manage state with Redux, and I thought I would implement a more modern way. However, I cannot firgure out why my state is undefined in my page. Here are my codes:
//IProduct.ts
export default interface IProduct {
_id: string;
image: string;
name: string;
rating: number;
numReviews: number;
price: number;
description: string;
countInStock: number;
}
//productSlice.ts
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import IProduct from "../../entities/IProduct";
import axios from "axios";
export const fetchProducts = createAsyncThunk<
IProduct[],
void,
{ rejectValue: string }
>("products/fetchProducts", async (_, thunkAPI) => {
try {
const { data } = await axios.get("/api/products");
return data;
} catch (error) {
return thunkAPI.rejectWithValue("Failed to fetch products.");
}
});
interface ProductsState {
products: IProduct[];
loading: boolean;
error: string | null;
}
const initialState: ProductsState = {
products: [],
loading: false,
error: null,
};
export const productsSlice = createSlice({
name: "products",
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchProducts.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(fetchProducts.fulfilled, (state, action) => {
state.loading = false;
state.products = action.payload;
})
.addCase(fetchProducts.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message || "Something went wrong";
});
},
});
export default productsSlice.reducer;
//store.ts
import { configureStore } from "@reduxjs/toolkit";
import { useDispatch } from "react-redux";
import productsSliceReducer from "./product/productSlice";
export const store = configureStore({
reducer: {
products: productsSliceReducer,
},
});
export default store;
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
//HomeScreen.tsx
import { useSelector } from "react-redux";
import { Row, Col } from "react-bootstrap";
import { useEffect } from "react";
import Product from "../components/Product";
import Loader from "../components/Loader";
import Message from "../components/Message";
import { RootState } from "../state/store";
import { useAppDispatch } from "../state/store";
import { fetchProducts } from "../state/product/productSlice";
function HomeScreen() {
const dispatch = useAppDispatch();
const productsList = useSelector((state: RootState) => state.products);
const { error, loading, products } = productsList;
useEffect(() => {
console.log(products);
dispatch(fetchProducts());
}, [dispatch]);
return (
<div>
<h1>Latest Products</h1>
{loading ? (
<Loader />
) : error ? (
<Message variant="danger">{error}</Message>
) : (
<Row>
{products.map((product) => (
<Col key={product._id} sm={12} md={6} lg={4} xl={3}>
<Product product={product} />
</Col>
))}
</Row>
)}
</div>
);
}
export default HomeScreen;
//main.tsx
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import { Provider } from "react-redux";
import "./index.css";
import "./bootstrap.min.css";
import store from "./state/store.ts";
ReactDOM.createRoot(document.getElementById("root")!).render(
<Provider store={store}>
<App />
</Provider>
);
Screenshot of the error undefined
Many thanks in advance!
I have checked my createAsyncThunk output and it's definitely returning values, and I can see them on my frontend as well. Not sure what is causing the 'undefined' state under the Redux devtool