You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中修改按钮文本后,如何触发Redux-thunk的dispatch?

Fixing the "Add/Remove from Cart" Button Behavior

Let's break down the issues in your current code and fix them step by step:

The Immediate Fix

The core problem in your updateCart function is that in the if branch, you defined an arrow function but never executed it—so the addToCart dispatch never runs. Plus, we can clean up the logic to ensure the button text updates first, then the Redux action fires.

Here's the corrected updateCart method:

updateCart(event, id) {
  // Store the button element in a variable to avoid potential target changes
  const cartButton = event.target;
  
  if (cartButton.textContent.trim() === 'Add to cart') {
    // First update the button text immediately
    cartButton.textContent = 'Remove from cart';
    // Trigger the Redux dispatch to add the item
    const currentCount = this.props.cartcount.cartcount;
    this.props.addToCart(id, currentCount);
  } else {
    // Update text first, then dispatch the removal
    cartButton.textContent = 'Add to cart';
    const currentCount = this.props.cartcount.cartcount;
    this.props.subtractFromCart(id, currentCount);
  }
}

Key Fixes:

  • Executed the dispatch: Removed the unused arrow function wrapper around this.props.addToCart—now it runs immediately after updating the button text.
  • Trimmed text check: Added .trim() to handle any accidental whitespace in the button text, making the check more reliable.
  • Stored the button element: Using cartButton instead of repeating event.target is a safer practice (prevents issues if the event target changes unexpectedly).

A Better Approach: Avoid Relying on DOM Text for State

While the above fix works, relying on the button's text content to determine its state is fragile (e.g., if you later add localization or modify the text). Instead, drive the button state from your Redux store.

Step 1: Pass Cart Status to RenderBooks

In your Books component's render method, check if each book is already in the cart, then pass that state to RenderBooks:

render() {
  const count = this.props.cartcount.cartcount;
  // Assuming you have a cartItems array in your Redux state with book IDs
  const { cartItems } = this.props;

  const bookElements = this.props.books.books.map((book, index) => {
    const isInCart = cartItems.some(item => item.id === book.id);
    return (
      <div key={index} className="col-8 col-md-4 col-lg-3">
        <RenderBooks 
          book={book} 
          updateCart={this.updateCart} 
          isInCart={isInCart} />
      </div>
    );
  });

  // ... rest of your render code
}

Step 2: Set Button Text from Redux State

Update RenderBooks to use the isInCart prop instead of hardcoding the initial text:

function RenderBooks({book, updateCart, isInCart}) {
  return(
    <Card className="allbooks">
      {/* ... existing card content ... */}
      <form>
        <Button 
          className="add-to-cart" 
          style={{textDecoration:'none'}} 
          color="link" 
          onClick={(e) => updateCart(e, book.id)} >
          {isInCart ? 'Remove from cart' : 'Add to cart'}
        </Button>
      </form>
    </Card>
  );
}

Step 3: Update updateCart to Use Redux State

Now your updateCart function can rely on the Redux state instead of DOM text:

updateCart(event, id) {
  const { cartItems } = this.props;
  const isInCart = cartItems.some(item => item.id === id);
  const cartButton = event.target;

  if (!isInCart) {
    cartButton.textContent = 'Remove from cart';
    const currentCount = this.props.cartcount.cartcount;
    this.props.addToCart(id, currentCount);
  } else {
    cartButton.textContent = 'Add to cart';
    const currentCount = this.props.cartcount.cartcount;
    this.props.subtractFromCart(id, currentCount);
  }
}

This approach makes your component more predictable—your UI state is always synced with your Redux store, instead of relying on DOM elements to track state.

内容的提问来源于stack exchange,提问作者Uwem Uke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:52:45