reactjs React组件:需要单击+或-按钮两次才能更新计数-是什么导致了这种行为?

ycggw6v2  于 12个月前  发布在  React
关注(0)|答案(1)|浏览(104)

在我的React组件中,我实现了通过单击“+”和“-”按钮来增加和减少购物车中产品计数的功能。然而,我遇到了一个问题,我需要点击这些按钮两次才能看到计数的变化。这种行为是意外的,我正在寻求帮助来识别和解决问题。
我有一个名为Cart的React组件,它从API中检索购物车数据并显示它。它使用Redux-Toolkit中的updatecartcount函数来更新购物车中的产品计数。

import { Box, Button, Grid, Typography } from '@mui/material'
import axios from 'axios'
import { ErrorMessage } from 'formik'
import React, { useEffect, useState } from 'react'
import { useDispatch } from 'react-redux'
import { updatecartcount } from './updatecount'

export default function Cart() {
  const dispatch = useDispatch()
  const [cart, setcart] = useState([])
  const [error, seterror] = useState('')
        
  async function getcart() {
    try {
      const response = await axios.get('https://ecommerce.routemisr.com/api/v1/cart', {
        headers: { token: localStorage.getItem('acesstoken') }
      });
      console.log(response.data.data.products);
      setcart(response.data.data);
    } catch (err) {
      seterror(err);
    }
  }         
            
  useEffect(() => {
    getcart()
  },[])

  return
    <>
      <Typography variant='h6'>your cart</Typography>
        <Typography variant='h6'>total cart price : {cart.totalCartPrice} EGP</Typography>
        {cart.products? cart.products.map((product) => 
          <Grid
            container sx={{
              width: 3/4,
              margin: 'auto',
              display: 'flex',
              alignItems: 'center'
            }}
          >
            <Grid md={1}> 
              <Box sx={{ backgroundColor: 'red', width: '100%' }}>
                <img
                  src={product.product.imageCover}
                  width={'100%'}
                />
              </Box>
            </Grid>
            <Grid md={9}> 
              <Box
                sx={{
                  width: '100%',
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center'
                }}
              > 
              <Box>
                <Typography
                  sx={{
                    textAlign: 'center',
                    marginRight: '1rem'
                  }}
                >
                  product: {product.product.title}
                </Typography>
                <Typography sx={{ textAlign: 'center' }}>
                  price={product.price}
                </Typography>
              </Box>
              <Box
                sx={{
                  display: 'flex',
                  justifyContent: 'center',
                  alignItems: 'center'
                }}
              >
                <Button
                  onClick={() => {
                    dispatch(updatecartcount({
                      id: product.product._id,
                      count: product.count - 1
                    }))
                    getcart()
                  }}
                >
                  -
                </Button>
                <Typography>{product.count}</Typography>
                <Button
                  onClick={() => {
                    dispatch(updatecartcount({
                      id: product.product._id, 
                      count: product.count + 1
                    }))
                      .then(getcart())
                  }}
                >
                  +
                </Button>
              </Box>
            </Box>
          </Grid>
        </Grid>
      ) : ''}
    </>
}
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";

export const updatecartcount = createAsyncThunk(
  'cartcount/updatecartcount',
  async function ({ id, count }) {
    let { data }= axios.put(
      `https://ecommerce.routemisr.com/api/v1/cart/${id}`,
      {
        count: count
      },
      {
        headers: {
          token: localStorage.getItem('acesstoken')
        }
      }
    )
    return data
  }
)

export const updatecartslice = createSlice({
  name: 'cartCount',
  initialState: {
    cartcount: []
  },
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(updatecartcount.fulfilled, (state, action) => {
      state.cartcount = action.payload
    })
  }
})

export const updateCountSlice=updatecartslice.reducer

如何确保单击一次按钮后计数立即更新?在我的React组件或Redux实现中是否有任何潜在的问题可能导致这个问题?

u1ehiz5o

u1ehiz5o1#

要在dispatch上的fulfillederror之后运行代码,请尝试先将其展开以获得类似Promise的行为。

dispatch(
    updatecartcount({
    id: product.product._id,
    count: product.count + 1,
    })
)
.unwrap()
.then(getcart());

关于Redux
然而,通常需要编写逻辑来查看实际请求的成功或失败。Redux Toolkit向返回的Promise添加了一个.unwrap()函数,它将返回一个新的Promise,该Promise具有来自fulfilled操作的实际action.payload值,或者如果它是被拒绝的操作,则具有throws an error值。这允许我们使用普通的try/catch逻辑来处理组件中的成功和失败。因此,如果文章成功创建,我们将清除输入字段以重置表单,如果失败,则将错误记录到控制台。

相关问题