使用redux工具包MERN从数组中删除选定值

qvsjd97n  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(103)

使用MERN堆栈制作的电子商务应用程序,在此应用程序中,我使用redux工具包和persist处理状态(我是新来的redux/redux工具包).我有一个问题,在我的cartReducers.所以我想删除某些项目在我的购物车,但我有麻烦完成任务.问题是当我运行cartReducers我的数据在购物车状态不删除我尝试使用过滤器,我改变了数组,但它不工作。我需要帮助和解释我的问题。谢谢

  • 问题出在购物车页面 *

cartRedux:

import { createSlice } from '@reduxjs/toolkit'

const cartSlice = createSlice({
    name: "cart",
    initialState: {
        products: [],
        quantity: 0,
        total: 0,
    },
    reducers: {
        addProduct: (state, action) => {
            state.quantity +=1;
            state.products.push(action.payload);
            state.total += action.payload.price * action.payload.quantity;
        },
        removeItem: (state, action) => {
            state.products.splice(state.products.findIndex((arrow) => arrow.id === action.payload), 1);
        }
    }
})

export const { addProduct, removeItem } = cartSlice.actions
export default cartSlice.reducer;

店铺:

import { configureStore, combineReducers } from "@reduxjs/toolkit"
import cartReducer from './cartRedux'
import userReducer from './userRedux'
import {
    persistStore,
    persistReducer,
    FLUSH,
    REHYDRATE,
    PAUSE,
    PERSIST,
    PURGE,
    REGISTER,
  } from "redux-persist";
import storage from "redux-persist/lib/storage"

const persistConfig = {
  key: "root",
  version: 1,
  storage,
};

const rootReducer = combineReducers({ user: userReducer, cart: cartReducer });

const persistedReducer = persistReducer(persistConfig, rootReducer);
  
export const store = configureStore({
    reducer: persistedReducer,
    middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
})

export let persistor = persistStore(store);

API调用:

export const login = async (dispatch, user) => {
    dispatch(loginStart());
    try {
        const res = await publicRequest.post("/login", user);
        dispatch(loginSuccess(res.data));
    } catch (err) {
        dispatch(loginFailure());
    }
}

export const addToCart = async (dispatch, product, quantity, user) => {
    try {
        const res = await userMethod.post("/cart/create", {
            userId: product.user,
            products: product
        });
        dispatch(addProduct({ ...product }));
        console.log(product)
    } catch (err) {
        console.log(err);
    }
}

export const removeCartItem = async (dispatch, cartId, itemId) => {
    try {
        const res = await userMethod.delete(`/cart/delete/${cartId}`);
       dispatch(removeItem(itemId));
       console.log(itemId)
    } catch (err) {
        console.log(err);
    }
}

购物车页面:

const Cart = () => {

    const cart = useSelector(state=>state.cart);
   
    const [ stripeToken, setStripeToken ] = useState(null);
    const navigate = useNavigate();
    
    const onToken = (token) => {
        setStripeToken(token);
    }

    const dispatch = useDispatch();
    const user = useSelector((state) => state.user.currentUser._id);

    
    const [ cartProducts, setCartProducts ] = useState([]);

    useEffect(() => {
        const makeRequest = async () => {
            try{
                const response = await userMethod.post("/test", {
                    tokenId: stripeToken.id,
                    amount: 500,
                })
                navigate("/success", { state: {stripeData: response.data, products: cart} });
            } catch (err) {
            } 
        }
        stripeToken &&  makeRequest();
    }, [stripeToken, cart.total, navigate])

    useEffect(() => {
        const makeCartRequest = async () => {
            try{
                const response = await userMethod.get(`/test${user}`)
                setCartProducts(response.data);
            } catch (err) {
                console.log(err);
            } 
        }
        makeCartRequest();
    }, [user?._id])

    
    const deleteCart = (cartId, itemId) => {
        removeCartItem(dispatch, cartId, itemId);
        window.location.reload();
    }


  return (
    <Container>
        <Navbar />
        <Wrapper>
            <Title>Your Bag</Title>
            <Top>
                <TopButton onClick={deleteCart}>Continue Shopping</TopButton>
                <TopTexts>
                    <TopText>Shooping Bag({cart.quantity})</TopText>
                    <TopText>Your Wishlist</TopText>
                </TopTexts>
                <TopButton type="filled">Checkout Now</TopButton>
            </Top>
            <Bottom>
                <Info>
                {cartProducts.map((product) => (
                    <Product>
                        <ProductDetail>
                            <Image src={product.products[0].img} alt="google"></Image>
                            <Details>
                                <ProductName><b>Product:</b> {product.products[0].title}</ProductName>
                                <ProductId><b>ID:</b> {product.products[0]._id}</ProductId>
                                <Button onClick={() => {
                                    deleteCart(product._id, product.products[0]._id)
                                }}>Delete</Button>
                            </Details>
                        </ProductDetail>
                        <PriceDetail>
                            <ProductAmountContainer>
                                <AiOutlineMinus />
                                <ProductAmount>{product.products[0].quantity}</ProductAmount>
                                <GrAdd />
                            </ProductAmountContainer>
                            <ProductPrice>$ {product.products[0].price * product.products[0].quantity}</ProductPrice>
                        </PriceDetail>
                    </Product>
                        ))}
                    <Hr></Hr>
                </Info>
                <Summary>
                    <SummaryTitle>Order Summary</SummaryTitle>
                        <SummaryItem>
                            <SummaryItemText>Subtotal</SummaryItemText>
                            <SummaryItemPrice>$ {cart.total}</SummaryItemPrice>
                        </SummaryItem>
                        <SummaryItem>
                            <SummaryItemText>Estimated Shipping</SummaryItemText>
                            <SummaryItemPrice>$ 5</SummaryItemPrice>
                        </SummaryItem>
                        <SummaryItem>
                            <SummaryItemText>Shipping Discount</SummaryItemText>
                            <SummaryItemPrice>$ -6</SummaryItemPrice>
                        </SummaryItem>
                        <SummaryItem>
                            <SummaryItemText type="total">Total</SummaryItemText>
                            <SummaryItemPrice>$ {cart.total}</SummaryItemPrice>
                        </SummaryItem>
                        <StripeCheckout 
                            name="Kimia shop" 
                            image="https://d3o2e4jr3mxnm3.cloudfront.net/Mens-Jake-Guitar-Vintage-Crusher-Tee_68382_1_lg.png"
                            billingAddress
                            shippingAddress
                            description={`your total is $ ${cart.total}`}
                            amount={cart.total * 100}
                            token={onToken}
                            stripeKey={KEY}
                            >
                            <Button>Checkout Now</Button>
                        </StripeCheckout>
                </Summary>
            </Bottom>
        </Wrapper>
        <Footer />
    </Container>
  )
}

export default Cart
hgqdbh6s

hgqdbh6s1#

据我所知,您实际上并没有将任何操作分派到存储区以移除/删除任何项目。removeCartItem操作仍然需要在deleteCart处理程序中分派到存储区。

const dispatch = useDispatch();

...

const deleteCart = (cartId, itemId) => {
  dispatch(removeCartItem(dispatch, cartId, itemId));
};

你也在使用redux-toolkit,但似乎仍然在写“旧的redux”代码。removeCartItem是一个“Thunk”式的函数,所以使用createAsyncThunk并创建一个真实的的Thunk。
示例:

import { createAsyncThunk } from '@reduxjs/toolkit';

export const removeCartItem = createAsyncThunk(
  "cart/removeItem",
  async (cartId, thunkAPI) => {
    try {
      const res = await userMethod.delete(`/cart/delete/${cartId}`);
    } catch (error) {
      console.log(error);
      return thunkAPI.rejectWithValue(error);
    }
  }
);
const initialState = {
  products: [],
};

const cartSlice = createSlice({
  name: "cart",
  initialState,
  reducers: {
    addProduct: (state, action) => {
      state.products.push(action.payload);
    },
    removeItem: (state, action) => {
      const index = state.products.findIndex((item) => item._id === action.payload);
      if (index !== -1) {
        state.products.splice(index, 1);
      }
    }
  }
});

export cartProductsSelector = state => state.cart.products;
export cartQuantitySelector = state => state.cart.products.length;
export cartTotalSelector = state => state.cart.products.reduce(
  (total, { price = 0, quantity = 1 }) => total + quantity * price,
  0,
);

请注意,“total”和“quantity”从cart状态切片中删除,因为它们是派生的“state”,选择器函数被导出以替换它们。

const Cart = () => {
  const cartProducts = useSelector(cartProductsSelector);
  const cartQuantity = useSelector(cartQuantitySelector);
  const cartTotal = useSelector(cartTotalSelector);

  ...

  const deleteCart = async (cartId, itemId) => {
    try {
      // Asynchronous call to backend, wait to resolve
      await dispatch(removeCartItem(cartId)).unwrap;

      // Now dispatch action to remove item from state
      dispatch(removeItem(itemId));
    } catch(error) {
      // handle any errors
    }
  };

  ...
};

相关问题