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值

以编程方式路由与 redux 反应

redux-saga-test-plan put 效果不匹配,但实际和预期的有效负载相等

在react / redux中排队AJAX请求

我的反应应用程序中的消息如何解决这个问题

使用 redux-saga 作为中间件,在 root saga 文件中使用的 All 效果和 Fork 效果都比较有用