【发布时间】:2021-11-03 16:38:10
【问题描述】:
问题截图:https://streamable.com/ofn42v
它在本地运行良好,但一旦部署到生产(vercel),它就无法运行。我已经尝试了很多不同的事情,比如在购物车中有一个单独的状态,useEffect 和 totalQuantity 在依赖数组中,但似乎没有任何效果。理想情况下,当上下文中的totalQuantity 更新时,使用它的组件应该按照react doc 中的说明重新渲染,这发生在n 到2 之间,1 除外。有人可以帮忙吗:(
导航栏中购物车图标的代码:
function Cart(props) {
const { enableCart, totalQuantity } = useContext(AppContext);
return (
<>
{enableCart ? (
<Link href="/cart" passHref>
<a aria-label="Shopping cart" title="Shopping cart">
<Badge count={totalQuantity} offset={[0, 5]}>
<ShoppingCartIcon className="w-7 h-7" />
</Badge>
</a>
</Link>
) : null}
</>
);
}
更新数量-appContext中的代码:
import { useCookies } from "react-cookie";
export const AppProvider = (props) => {
const [cartItems, updateCart] = useState([]);
const [totalQuantity, setTotalQuantity] = useState(0);
const [cookies, setCookie] = useCookies(["cart"]);
const cookieCart = cookies.cart;
useEffect(() => {
cartOperations();
}, []);
const calculateAmountQuantity = (items) => {
let totalCount = 0;
let totalPrice = 0;
items.forEach((item) => {
totalCount += item.quantity;
totalPrice += item.price * item.quantity;
setTotalAmount(totalPrice);
setTotalQuantity(totalCount);
});
};
const cartOperations = async (items) => {
if (items !== undefined) {
updateCart([...items]);
calculateAmountQuantity(items);
} else if (cookieCart !== undefined) {
updateCart([...cookieCart]);
calculateAmountQuantity(cookieCart);
} else {
updateCart([]);
setTotalAmount(0);
setTotalQuantity(0);
}
};
const addItem = (item) => {
let items = cartItems;
let existingItem;
if (items) existingItem = items.find((i) => i.id === item.id);
if (!existingItem) {
items = [
...(items || []),
Object.assign({}, item, {
quantity: 1,
}),
];
updateCart([...items]);
setTotalAmount(totalAmount + item.price * 1);
setTotalQuantity(totalQuantity + 1);
} else {
const index = items.findIndex((i) => i.id === item.id);
items[index] = Object.assign({}, item, {
quantity: existingItem.quantity + 1,
});
updateCart([...items]);
setTotalAmount(totalAmount + existingItem.price);
setTotalQuantity(totalQuantity + 1);
}
saveCartToCookie(items);
saveCartToStrapi(items);
};
我将购物车内容存储在 cookie 中。
AppContext 的代码是 here in github,完整的 nav bar code
直播网址:https://sunfabb.com
转到产品,将几件商品添加到购物车,然后尝试从购物车页面中逐一删除。 (我也在 prod 中启用了 React Profiler)
编辑:这个问题完全是 antd 库特有的。我能够根据以下 2 个答案进一步调试,反应上下文或重新渲染没有任何问题。我尝试为购物车使用自定义徽章,它工作得很好。不过要解决 antd 问题。我可以用自定义的,但是antd的徽章加上一些动画效果更好。
【问题讨论】:
-
我建议您尝试的一个快速方法是改用
setTotalQuantity(value => value - 1)。我的猜测是这是一个陈旧的关闭问题。 -
感谢您的建议,但@hackape 似乎在这里不起作用。部署了您建议的更改here
-
此外,陈旧的关闭对我来说是新事物并进行了查找。根据here 的解释,它不应该从 n...2 中删除项目,但这里只有购物车中的最后一项导致问题。单凭这一点,它怎么会变得陈旧?
-
这只是一个盲目的猜测。您的应用程序非常复杂,此时我无法发现问题。但我可以看出 a) 它容易受到陈旧关闭问题的影响,并且 b) 我不会以这种方式管理
totalQuantity。它可以从cartItems派生/计算,手动设置它的值没有意义,它增加了不必要的复杂性并可能引入错误。 -
const [totalPrice, totalQuantity] = cartItems.reduce(([price, quantity], item) => [price + item.price, quantity + item.quantity], [0, 0])
标签: javascript reactjs next.js antd react-state-management