React购物车Button条件渲染失效 库存为0未显示禁用缺货按钮
购物车商品库存状态按钮渲染异常问题
问题表现
- 预期效果:商品库存为0(售罄)时,购买按钮自动禁用,展示「Out of stock」缺货提示
- 实际异常:库存归0后页面始终展示可点击的「Add to cart」按钮,未切换到禁用缺货状态
关联业务代码
import { Button } from 'react-bootstrap'; import { Card } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import React, { useContext } from 'react'; import Rating from './Rating'; import axios from 'axios'; import { Store } from '../Store'; function Product(props){ const {product} = props; const {state , dispatch:ctxDispatch} = useContext(Store); const {cart: {cartItems}} = state const addToCartHandler = async (item )=>{ const existItem = cartItems.find((x)=> x._id === product._id); const quantity = existItem ? existItem.quantity+1 : 1; const {data} = await axios.get(`/api/products/${item._id}`); if(data.countInStock < quantity){ window.alert('sorry product is out of stock') return; } ctxDispatch({ type:'CART_ADD_ITEM', payload:{...item , quantity}, }); }; return( <Card> <Link to={`/product/${product.slug}`}> <img src={product.image} className="card-img-top" alt={product.name} /> </Link> <Card.Body> <Link to={`/product/${product.slug}`}> <Card.Title>{product.name}</Card.Title> </Link> <Rating rating={product.rating} numReviews={product.numReviews} /> <Card.Text>${product.price}</Card.Text> {product.countInStock === 0 ? ( <Button color="light" disabled={true}>Out of stock</Button> ):( <Button onClick={() => addToCartHandler(product)}>Add to cart</Button> )} </Card.Body> </Card> ) }
问题根因
代码一共存在3处会导致渲染异常的问题:
- 严格相等判断的类型不匹配:渲染分支判断用了
===严格相等校验product.countInStock === 0,如果后端接口返回的countInStock是字符串格式的"0"(不少后端接口会默认把数字类型字段序列化为字符串返回),数字0和字符串"0"做严格相等比较结果为false,永远不会进入缺货按钮的渲染分支。 - 渲染依赖的库存数据未实时更新:加购逻辑里虽然调用接口查询了商品最新库存做超卖拦截,但接口返回的最新库存值没有同步更新到组件渲染依赖的
product对象上,组件始终用页面初始加载时拿到的旧库存值做判断,哪怕库存已经被加购消耗到0,也不会触发重渲染切换按钮状态。 - 第三方组件属性传参错误:缺货状态的Button组件传入了不存在的
color="light"属性,React Bootstrap的Button组件用variant属性控制主题样式,而非color,就算判断逻辑正常生效,按钮样式也无法按预期展示。
修复方案
对应3个问题点逐一修改即可:
- 统一库存字段的类型后再做判断,把判断条件改为
Number(product.countInStock) === 0,从根源避免类型不一致导致的判断失效 - 加购接口返回最新库存数据后,同步更新本地商品列表中对应商品的
countInStock值,保证组件渲染依赖的库存数据是最新值,状态变化时可以正常触发重渲染 - 把缺货Button的
color="light"属性替换为组件支持的variant="light"属性,保证按钮样式正常展示
内容的提问来源于stack exchange,提问作者elias
相关产品推荐
相关产品推荐

