React-redux State Undefined

55 Views Asked by At

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

0

There are 0 best solutions below