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

React中使用useState实现点击移除数组元素的技术问询

实现点击按钮切换数组元素的添加/移除功能

这是个很典型的「选中/取消选中」交互需求,咱们只需要修改核心逻辑函数,同时完善按钮的选中状态反馈就能搞定。

第一步:修改handleAdd函数,实现Toggle逻辑

原来的代码里当值已存在时没有做任何操作,现在我们要补充「移除」的逻辑。另外,因为新状态依赖旧状态,推荐用函数式更新的方式调用setCheckCredit,这样能确保拿到最新的状态值,避免异步更新导致的问题:

function handleAdd(e, val) {
  setCheckCredit(prevCredit => {
    if (prevCredit.includes(val)) {
      // 值已存在,过滤掉该元素实现移除
      return prevCredit.filter(item => item !== val);
    } else {
      // 值不存在,添加到数组中
      return [...prevCredit, val];
    }
  });
}

第二步:给按钮添加选中状态反馈

你的Card组件已经预留了selected属性,但之前的代码没正确传递这个值。现在我们可以根据checkCredit数组是否包含当前卡片的creditAvailable来设置这个属性,让用户能直观看到哪个按钮处于选中状态:

修改Cardlist里的Card渲染代码:

<Card 
  id={detail.id}
  title={detail.title}
  apr={detail.apr}
  onClick={(e) => handleAdd(e, detail.creditAvailable)}
  balanceOfferDuration={detail.balanceOfferDuration}
  purchaseOfferDuration={detail.purchaseOfferDuration}
  creditAvailable={detail.creditAvailable}
  // 新增:判断当前卡片是否被选中
  selected={checkCredit.includes(detail.creditAvailable)}
/>

第三步:优化底部金额显示格式

原来直接渲染数组会显示成逗号拼接的字符串,我们可以优化一下,数组为空时显示0,多个元素时用逗号分隔,体验更友好:

<div>
  Credit Available: £{checkCredit.length > 0 ? checkCredit.join(", ") : "0"}
</div>

完整修改后的Cardlist组件代码

import React, { useState } from "react";
import PropTypes from "prop-types";
import Card from "./Card";
import { studentPayload, liquidCardPayload, anywhereCardPayload } from "../data/cardData";

const Cardlist = ({ incomeData, employmentData }) => {
  const [checkCredit, setCheckCredit] = useState([]);
  let payloads = [anywhereCardPayload];
  
  // 简化卡片筛选逻辑,避免重复判断
  if (employmentData === "student") {
    payloads.push(studentPayload);
  }
  if (incomeData >= 15000) {
    payloads.push(liquidCardPayload);
  }

  function handleAdd(e, val) {
    setCheckCredit(prevCredit => {
      if (prevCredit.includes(val)) {
        return prevCredit.filter(item => item !== val);
      } else {
        return [...prevCredit, val];
      }
    });
  }

  return (
    <React.Fragment>
      {payloads.map(detail => (
        <div key={detail.id}> {/* 用唯一id作为key比title更可靠 */}
          <Card 
            id={detail.id}
            title={detail.title}
            apr={detail.apr}
            onClick={(e) => handleAdd(e, detail.creditAvailable)}
            balanceOfferDuration={detail.balanceOfferDuration}
            purchaseOfferDuration={detail.purchaseOfferDuration}
            creditAvailable={detail.creditAvailable}
            selected={checkCredit.includes(detail.creditAvailable)}
          />
        </div>
      ))}
      <div>
        Credit Available: £{checkCredit.length > 0 ? checkCredit.join(", ") : "0"}
      </div>
    </React.Fragment>
  );
};

Cardlist.propTypes = {
  incomeData: PropTypes.string.isRequired,
  employmentData: PropTypes.string.isRequired
};

export default Cardlist;

补充说明

  • 函数式更新setCheckCredit(prev => ...)是因为React状态更新可能异步,这样能确保基于最新状态修改,避免闭包导致的旧状态问题。
  • 把key从detail.title改成detail.id更可靠,因为标题可能重复,但id是唯一标识。
  • 简化了卡片筛选逻辑,原来的重复判断可以合并,代码更简洁易读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 09:42:51