繁体   English   中英

调度后 Reacjs redux 工具包和 axios 在控制台上显示未定义

[英]Reacjs redux toolkit and axios after dispatching shows undefined on console

这是我对productSlice.js的实现

import { createSlice,createSelector,PayloadAction,createAsyncThunk,} from "@reduxjs/toolkit";
import axios from 'axios';

export const getProducts = createAsyncThunk(
    'product/getProducts', 
    async (_,thunkAPI) => {
        try {
        const response = await axios.get(`https://fakestoreapi.com/products`);
        const data = await response.json();
        return data;
        }
        catch (error) {
            return thunkAPI.rejectWithValue({ error: error.message });
    }
});

const productSlice=createSlice({
    name:'products',
    initialState:{
        products:[],
        status:'idle',
        error: "",
    },
    reducers:{},
    extraReducers:(builder)=>{
        builder.addCase(getProducts.pending,(state)=>{
            state.status="pending";
            state.products=[];
        }
    );
    builder.addCase(
        getProducts.fulfilled, (state, { payload }) => {
            state.products.push(payload);
            state.status = "succeeded";
        });
     builder.addCase(
       getProducts.rejected,(state, action) => {
           state.status = "error";
           state.error = action.error.message;
     });
    },
},);

export const selectProducts = createSelector(
    (state) => ({
       products: state.products,
         status: state.status,
    }), (state) =>  state
  );

export default productSlice.reducer;

这是我的store.js

import { configureStore } from "@reduxjs/toolkit";

import typeReducer from "../features/types/typeSlice";
import productReducer from "../features/Product/productSlice";

export const store = configureStore({
  reducer: {
    type: typeReducer,
    product: productReducer,
  },
});

和我发送它的组件。 产品.js

import { Rating } from "@mui/material";
import axios from "axios";
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import {useDispatch, useSelector} from 'react-redux';
import {getProducts,selectProducts} from '../../features/Product/productSlice';

const Product = () => {
  const dispatch = useDispatch();
  const fetchProducts = useSelector(selectProducts);
  const [product, setProduct] = useState([]);
  // const [loading, setLoading] = useState(false);
  // const [error, setError] = useState(null);

  
 

  useEffect(() => {
    dispatch(getProducts());
  }, [dispatch]);
  useEffect(() => {
    setProduct(fetchProducts);
  }
  , [fetchProducts]);

  //Console
  console.log(fetchProducts);
  console.log(product);




  const AddButton = ({ ...props }) => (
    <AddSubtractButton {...props}>+</AddSubtractButton>
  );
  
  const SubtractButton = ({ ...props }) => (
    <AddSubtractButton {...props}> &#8210;</AddSubtractButton>
  );

  return(
    <Wrapper>
      {Array.from(product).map((item) => (
        <Column key={item.id}>
          <IMG src={item.image} alt={item.name} />
          <H4>{item.title}</H4>
          <Rating style={{ paddingTop: "5px", fontSize:"14px", }} value={4} />
          <Price>${item.price}</Price>
  
            <div>
              <AddButton />
              <span>{item.quantity}</span>
              <SubtractButton />
            </div>
  
            <Button >Add to Cart</Button>
          <Price>Added!</Price>
        </Column>
      ))}
    </Wrapper>
  );
    }

  export default Product;

  const Column = styled.article`
    display: flex;
    flex-flow: column;
    align-items: center;
    border: 0.5px solid #999999;
    width: 350px;
    height: 350px;
    box-shadow: 0px 2px 1px -1px rgba(0, 0, 0, 0.2),
      0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
    padding: 12px 20px;
    border-radius: 10px;
    margin: 8px;
    background-color: #f2f2f2;
  `;
  const Wrapper = styled.div`
    max-width: 100%;
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-items: flex-start;
  `;
  const IMG = styled.img`
    padding:1px 8px;
    width: 150px;
    height: 150px;
    object-fit: contain;
    
  `;
  const Button = styled.button`
  user-select: none;
  border-radius: 10px;
  border: none;
  font-size: 15px;
  box-shadow: 0px 2px 1px -1px rgba(0, 0, 0, 0.2),
    0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
  background-color: ${({ backgroundColor }) => backgroundColor || "green"};
  padding: 10px 16px;
  color: white;

  margin: 5px;
  &:hover {
    opacity: 0.9;
    cursor: pointer;
  }
  transition: opacity 0.3s;
`;
  const H4 = styled.h4`
    padding: 12px 0;
    font-size: 13px;
    text-align: center;
    font-weight: bold;
    word-wrap:break-word ;
    /* word-break: break-all; */
    overflow: hidden;
    margin-bottom: 5px;
  `;
  
const Price = styled.p`
  font-size: 14px;
  padding: 2px 0;
  margin-bottom: 2px;
`;

const AddSubtractButton = styled(Button).attrs(() => ({
  backgroundColor: "darkGray"
}))`
  font-weight: 900;
  font-size: 18px;
  padding: 2px 8px;
`;

问题是当我发送getProducts()

 useEffect(() => {
    dispatch(getProducts());
  }, [dispatch]);
  useEffect(() => {
    setProduct(fetchProducts);
  }
  , [fetchProducts]);

它在控制台上显示未定义或 null。 请参阅下面的快照。

控制台输出

我是 redux初学者,尝试在我的项目中学习和实施。 我不知道我错过了什么,请帮我解决这个错误。

您的数据在state.product.products中,而不是在state.products中,因此您需要相应地编写选择器:


export const selectProducts = createSelector(
    state => state.product,
    (productSliceState) => ({
       products: productSliceState.products,
         status: productSliceState.status,
    })
  );

也就是说:您是否按照官方 Redux 教程进行到底? 您很可能希望使用 RTK Query 来获取数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM