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
相关产品推荐
相关产品推荐

