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

React组件复用同一OnClick Handler导致选中值被覆盖的问题

React Swatches组件选中状态丢失问题修复

问题描述

点击颜色选项时,选中数组能正确记录颜色选择:

[
    {
        "option_id": "159",
        "option_value": "167"
    }
]

但点击尺寸选项后,选中数组会被覆盖,仅保留尺寸的选择:

[
    {
        "option_id": "93",
        "option_value": "59"
    }
]

期望结果是同时保留颜色和尺寸的选中记录:

[
    {
        "option_id": "159",
        "option_value": "167"
    },
    {
        "option_id": "93",
        "option_value": "59"
    }
]

问题原因

组件里用let selected = []声明的是普通变量,React组件每次重新渲染时,这个变量都会被重置为空数组,导致之前的选中状态无法持久保存。

修复方案

用React的useState钩子管理选中状态,确保状态在组件渲染周期内被保留,同时修正函数名的拼写错误。

修复后的完整代码

import React, { useState } from "react";

const Swatches = (props) => {
  const options = props.options;
  const label = Object.keys(options);
  const values = Object.values(options);
  const colors = props.colors;
  const sizes = props.sizes;
  // 使用useState持久化选中状态
  const [selected, setSelected] = useState([]);

  const selectedOption = (e) => {
    const optionId = e.target.dataset.id;
    const optionValue = e.target.dataset.value;
    // 基于最新状态更新,避免状态覆盖
    setSelected(prevSelected => {
      const index = prevSelected.findIndex(x => x.option_id === optionId);
      if (index === -1) {
        // 新增未选中过的选项
        return [...prevSelected, { option_id: optionId, option_value: optionValue }];
      } else {
        // 更新已有选项的选中值
        const updatedList = [...prevSelected];
        updatedList[index].option_value = optionValue;
        return updatedList;
      }
    });
  };

  return (
    <React.Fragment>
      {values.length > 0 && (
        <div>
          <div className="flex middle-xs mb-15">
            <div className="fs-16 fw-5 c-main-gray">
              Pick your <span className="option-label">{label}</span>
            </div>
          </div>
          {label == "color" && colors?.options?.length > 0 && (
            <div className="flex flex-wrap size-unit-list">
              {colors?.options?.map((option, index) => (
                <React.Fragment key={index}>
                  {values[0].indexOf(parseInt(option.value)) > -1 && (
                    <div
                      className="fs-14 fw-5 c-dark-gray ta-c pt-6 pb-6 pl-10 pr-10 mw-40 mb-10 b-light-gray b-box size-button br-3 pos-relt mr-r-10 h-33 w-33"
                      style={{ backgroundColor: option?.label }}
                      data-id={colors.id}
                      data-value={option.value}
                      role="button"
                      onClick={selectedOption}
                    ></div>
                  )}
                </React.Fragment>
              ))}
            </div>
          )}
          {label == "size" && sizes?.options?.length > 0 && (
            <div className="flex flex-wrap size-unit-list">
              {sizes?.options?.map((option, index) => (
                <React.Fragment key={index}>
                  {values[0].indexOf(parseInt(option.value)) > -1 && (
                    <div
                      className="fs-14 fw-5 c-dark-gray ta-c pt-6 pb-6 pl-10 pr-10 mw-40 mb-10 b-light-gray b-box size-button br-3 pos-relt mr-r-10"
                      data-id={sizes.id}
                      data-value={option.value}
                      role="button"
                      onClick={selectedOption}
                    >
                      <span className="lh-ar-2 en-font">{option.label}</span>
                    </div>
                  )}
                </React.Fragment>
              ))}
            </div>
          )}
        </div>
      )}
    </React.Fragment>
  );
};

export default Swatches;

关键修改点

  • 替换普通变量为useState钩子存储选中状态,保证状态在组件渲染间不丢失
  • 使用函数式更新setSelected(prevSelected => ...),确保基于最新的状态进行修改,避免并发更新问题
  • 修正函数名拼写错误:selecetedOption → selectedOption

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:57:56