【发布时间】:2021-03-24 16:25:52
【问题描述】:
我遇到了一个问题,即 react 未在状态中呈现更新后的 cartItems。状态更新得很好,但我删除的项目实际上并没有从渲染中删除。
我对 react、redux 和状态管理非常陌生,但我认为状态本身实际上并没有什么问题,而是如何/何时迭代项目以进行渲染。只有当我刷新页面时,它才能准确呈现。
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { Row, Col, ListGroup, Image, Button } from "react-bootstrap";
import Message from "../components/Message";
import { addToCart, removeFromCart } from "../actions/cartActions";
function Basket({ match, location, history }) {
const productId = match.params.id;
const qty = location.search ? Number(location.search.split("?")[1]) : 1;
const specID = location.search ? Number(location.search.split("?")[2]) : 0;
const dispatch = useDispatch();
const cart = useSelector((state) => state.cart);
const { cartItems } = cart;
useEffect(() => {
if (productId) {
dispatch(addToCart(productId, qty, specID));
}
}, [dispatch, productId, qty, specID]);
const removeFromCartHandler = (cartItem) => {
dispatch(removeFromCart(cartItem));
};
const checkoutHandler = () => {
history.push("/login?redirect=shipping");
};
return (
<Row>
<Col md={8}>
{cartItems.length === 0 ? (
<Message variant="primary">
Your cart is empty{" "}
<Link to="/">
<strong>Go Back</strong>
</Link>
</Message>
) : (
<div>
<Link to="/">
<strong>Go Back</strong>
</Link>
<ListGroup variant="flush">
{cartItems.map((item) => (
<ListGroup.Item key={item.product} className="cart">
<Row>
{/* <Col xs={4} md={2}>
<Image src={item.img} alt={item.name} fluid rounded />
</Col> */}
<Col xs={4} md={3}>
<Link to={`/product/${item.product}`}>{item.name}</Link> (
{item.size})
</Col>
<Col xs={2} md={2}>
£{item.price}
</Col>
<Col xs={6} md={3}>
Qty
</Col>
<Col xs={6} md={1}>
<Button
type="button"
variant="light"
onClick={() => removeFromCartHandler(item)}
>
<i className="fas fa-trash" />
</Button>
</Col>
</Row>
</ListGroup.Item>
))}
</ListGroup>
</div>
)}
</Col>
</Row>
);
}
export default Basket;
购物车的减速器。
import { CART_ADD_ITEM, CART_REMOVE_ITEM } from "../constants/cartConstants";
export const cartReducer = (
state = { cartItems: [{ specList: [{ price: [] }] }] },
action
) => {
switch (action.type) {
case CART_ADD_ITEM:
const item = action.payload;
const existItem = state.cartItems.find(
(x) => x.product === item.product && x.size === item.size
);
if (existItem) {
return {
...state,
cartItems: state.cartItems.map((x) =>
x.product === existItem.product ? item : x
),
};
} else {
return { ...state, cartItems: [...state.cartItems, item] };
}
case CART_REMOVE_ITEM:
return {
...state,
cartItems: state.cartItems.filter((x) => x !== action.payload),
};
default:
return state;
}
};
import axios from "axios";
import { CART_ADD_ITEM, CART_REMOVE_ITEM } from "../constants/cartConstants";
export const addToCart = (id, qty) => async (dispatch, getState) => {
const { data } = await axios.get(`/api/products/${id}`);
dispatch({
type: CART_ADD_ITEM,
payload: {
product: data._id,
name: data.name,
image: data.image,
price: data.price,
countInStock: data.countInStock,
qty,
},
});
localStorage.setItem("cartItems", JSON.stringify(getState().cart.cartItems));
};
export const removeFromCart = (id) => async (dispatch, getState) => {
dispatch({
type: CART_REMOVE_ITEM,
payload: id,
});
localStorage.setItem("cartItems", JSON.stringify(getState().cart.cartItems));
};
【问题讨论】:
-
你能把reducer贴出来吗?
-
您很可能正在改变
cartItems数组。你用splice吗? :) -
@HMR 我刚刚发布了它。谢谢。
-
@YuryTarabanko 不幸的是,我不知道这将如何实现。我还没用过拼接。
-
@rabin-bhandari NVM 我的猜测是错误的。添加
removeFromCart代码也可能会有所帮助。到目前为止,您发布的代码看起来还不错。
标签: javascript reactjs redux react-redux react-state-management