redux 和反应不需要的效果
Posted
技术标签:
【中文标题】redux 和反应不需要的效果【英文标题】:redux and react unwanted effect 【发布时间】:2021-02-06 16:15:32 【问题描述】:大家好????
-
我正在尝试使用 redux 制作购物车功能。
2.问题描述:
问题是,一旦我想从我的购物篮中移除一个不是最后一个的产品。
Redux 确实从商店中删除了所需的产品,但在前端我仍然看到该产品,并且 react 会从列表中删除最后一个产品(我不想删除的那个)。
我必须转到另一个页面而不重新加载并返回购物篮才能看到对重置的反应
如果我从列表中删除最后一个产品,则删除工作正常。
我制作了一个由谷歌驱动器提供的视频链接:
https://drive.google.com/file/d/1miZA4B1Ay5OZZBGPj1bCcQHsGv21oVW_/view
这是我想要或期望的 redux 效果(这是从购物车列表中删除最新产品的操作:
如果我的购物车中有多个产品,而我只想删除一个产品而不是最后一个(不需要的影响):
ADD_TO_CART_ACTION dispatch
store.dispatch(
type: ADD_PRODUCT_TO_CART_ACTION,
payload:
data:
productID: data.product.id,
attributeID: Radiostate,
price: data.price,
quantity: 1
)
这是我的购物车减速器:
export function CartReducer(state = [], action)
const cart = [...state]
switch (action.type)
case 'ADD_PRODUCT_TO_CART_ACTION':
return [...state, ...action.payload.data];
case 'UPDATE_QUANTITY_FROM_CART_ACTION':
return cart.map(product =>
if (product.attributeID === action.payload.attributeID)
product.quantity++
return ...product
else
return product
)
case 'REMOVE_QUANTITY_FROM_CART_ACTION':
return cart.map(product =>
if (product.attributeID === action.payload.attributeID)
product.quantity--
return ...product
else
return product
)
case 'TRASH_PRODUCT_FROM_CART_ACTION':
return cart.filter(product => product.attributeID !== action.payload)
default:
return state;
这是他们首先从 redux 连接的购物车组件:
export function Cart (props)
const [productCount, setProductCount] = useState(0)
useEffect(() =>
setProductCount(props.count)
, [])
if (props.cart.length === 0)
return <div className="home"><p className='text-center text-green-500'>Add product to cart.</p></div>
return (
<React.Fragment className="home">
<Grid container spacing=3>
props.cart.map((item, index) =>
return (
<Grid item xs=6>
<ProductCartDetails productCount=productCount key=index attributes=item/>
</Grid>
)
)
</Grid>
</React.Fragment>
)
export const CartStore = connect(
(state) => (
cart: cartSelectors(state),
count: cartCount(state)
)
)(Cart)
这是 ProductCartDetails(产品的卡片,这里是派发的动作)
export default function ProductCartDetails (props)
const [productCount, setProductCount] = useState(0)
const [product, setProduct] = useState([])
const [requestReady, setRequestReady] = useState(false)
useEffect(() =>
axios.get(`product/$props.attributes.productID`)
.then((data) =>
setProduct(data)
setRequestReady(! requestReady)
)
.catch((err) =>
console.log(err)
)
, [props.productCount])
useEffect(() =>
setProductCount(props.productCount)
, [props.productCount])
const useStyles = makeStyles((theme) => (
root:
display: 'flex',
width: "100%",
marginTop: 4,
backgroundColor: "#faf7f7",
boxSizing: 'border-box',
,
details:
display: 'flex',
flexDirection: 'column',
,
content:
flex: '1',
,
cover:
width: 151,
height: '100%'
,
));
const onClickAddMoreQuantity = () =>
let cart = [...store.getState()]
let updatedQuantity = false;
cart.map(product =>
if (product.attributeID === props.attributes.attributeID)
store.dispatch(
type: UPDATE_QUANTITY_FROM_CART_ACTION,
payload:
attributeID: props.attributes.attributeID
)
updatedQuantity = true
)
if (updatedQuantity === false)
swal(
icon: 'error',
title: 'Cart',
text: 'Product quantity cannot be bigger than the product stock.',
)
const onClickRemoveQuantityFromCart = () =>
let cart = [...store.getState()]
let updatedQuantity = false;
cart.map(product =>
if (product.attributeID === props.attributes.attributeID)
store.dispatch(
type: REMOVE_QUANTITY_FROM_CART_ACTION,
payload:
attributeID: props.attributes.attributeID
)
updatedQuantity = true
)
if (updatedQuantity === false)
swal(
icon: 'error',
title: 'Cart',
text: 'Product quantity has not been removed.',
)
const onClickTrashProductFromCart = () =>
let cart = [...store.getState()]
let updatedQuantity = false;
cart.map(product =>
if (product.attributeID === props.attributes.attributeID)
store.dispatch(
type: TRASH_PRODUCT_FROM_CART_ACTION,
payload: props.attributes.attributeID
)
updatedQuantity = true
)
if (updatedQuantity === false)
swal(
icon: 'error',
title: 'Cart',
text: 'Product has not been removed.',
)
const classes = useStyles();
if (productCount !== 0)
return (
<>
<Card className=classes.root>
<Link to=requestReady ? `/details/$product.slug` : null>
<img
className=classes.cover
src=requestReady ? axios.defaults.baseURL+product.image[0].url+"?h=600" : null
/>
</Link>
<div className=classes.details>
<CardContent className=classes.content>
<Typography className="text-center text-gray-700" component="h6" variant="h6">
requestReady ? product.name : null
</Typography>
<p className="text-center text-gray-600">
Details Of Product
</p>
<div>
<Typography variant="subtitle1" color="textSecondary">
Category: requestReady ? product.category.label : null
</Typography>
<Typography variant="subtitle1" color="textSecondary">
<ProductCartAttributeDetails attributes=props.attributes />
</Typography>
</div>
</CardContent>
<CardActions>
<button id=requestReady ? product.id : null onClick=onClickAddMoreQuantity>
<Add height=10 />Add quantity
</button>
<button>
<Delete height=10 onClick=onClickTrashProductFromCart />Trash
</button>
<button onClick=onClickRemoveQuantityFromCart>
<Remove height=10 />Remove quantity
</button>
</CardActions>
</div>
</Card>
</>
)
else
return (
<>
<Card className=classes.root>
<Link to=requestReady ? `/details/$product.slug` : null>
<img
className=classes.cover
src=requestReady ? axios.defaults.baseURL+product.image[0].url+"?h=600" : null
/>
</Link>
<div className=classes.details>
<CardContent className=classes.content>
<Typography className="text-center text-gray-700" component="h6" variant="h6">
requestReady ? product.name : null
</Typography>
<p className="text-center text-gray-600">
Details Of Product
</p>
<div>
<Typography variant="subtitle1" color="textSecondary">
Category: requestReady ? product.category.label : null
</Typography>
<Typography variant="subtitle1" color="textSecondary">
<ProductCartAttributeDetails attributes=props.attributes />
</Typography>
</div>
</CardContent>
<CardActions>
<button id=requestReady ? product.id : null onClick=onClickAddMoreQuantity>
<Add height=10 />Add quantity
</button>
<button>
<Delete height=10 onClick=onClickTrashProductFromCart />Trash
</button>
<button onClick=onClickRemoveQuantityFromCart>
<Remove height=10 />Remove quantity
</button>
</CardActions>
</div>
</Card>
</>
)
如果需要,ProductCartAttributeDetails
export default function ProductCartAttributeDetails(attributes)
const [attribute, setAttribute] = useState([])
const [requestReady, setRequestReady] = useState(false)
useEffect(() =>
axios.get(`attributes/$attributes.attributeID`)
.then((data) =>
setAttribute(data)
setRequestReady(! requestReady)
)
.catch((err) =>
console.log(err)
)
, [])
return (
<>
<Typography variant="subtitle1" color="textSecondary">
<p><span className="capitalize">requestReady ? attribute.attribute : null</span> : requestReady ? attribute.value : null</p>
</Typography>
<Typography variant="subtitle1" color="textSecondary">
<p>Quantity: requestReady ? attributes.quantity : null</p>
</Typography>
<Typography variant="subtitle1" color="textSecondary">
<p>Total Price: requestReady ? attribute.price * attributes.quantity : null</p>
</Typography>
</>
)
【问题讨论】:
您能说明您在哪里发货 ADD_PRODUCT_TO_CART_ACTION 吗?代码 我已经更新了帖子。 【参考方案1】:问题已通过您自己的索引更改 react js 的默认索引得到解决,对我来说,我使用从商店收到的索引来确保它们是唯一的
【讨论】:
以上是关于redux 和反应不需要的效果的主要内容,如果未能解决你的问题,请参考以下文章
React:Redux状态在一个效果中更新但在同一组件中的下一个效果是使用先前的state值