React中如何通过开关正确过滤并重新添加数组对象?
React数组操作问题:开关控制Sunday项增删异常修复
问题根源
你的代码里有三个核心错误:
- 用
JSON.stringify判断数组包含性不可靠:对象的属性顺序、空格差异都会导致匹配失效,而且性能低下。 - filter条件依赖数组索引而非明确值:
item.day !== business_hours[0].day会随着数组项的顺序变化误删其他元素——比如当Sunday被添加到数组末尾时,business_hours[0]是Monday,这时候过滤会删掉所有非Monday的项,完全违背了移除Sunday的初衷。 - 未使用函数式更新state:React的setState是异步操作,直接使用当前
business_hours可能拿到旧状态,导致逻辑混乱。
修复后的代码
直接针对Sunday的day字段做判断,并用函数式更新确保状态同步:
const onToggleSundaySwitch = () => { // 函数式更新开关状态,确保拿到最新值 setIsSundaySwitchOn(prev => !prev); // 函数式更新营业时间数组,基于最新状态操作 setBusinessHours(prevHours => { // 检查数组中是否已存在Sunday项 const hasSunday = prevHours.some(item => item.day === "Sunday"); if (hasSunday) { // 移除Sunday:过滤掉所有day为Sunday的项 return prevHours.filter(item => item.day !== "Sunday"); } else { // 添加Sunday:保持原数组顺序,添加到末尾(若想放开头可调整顺序) return [...prevHours, { "day": "Sunday", "open_time": "Not set", "close_time": "Not set" }]; } }); };
优化版逻辑(更贴合开关控制场景)
直接根据开关的新状态决定增删,逻辑更直观:
const onToggleSundaySwitch = () => { setIsSundaySwitchOn(prevSwitchState => { const newSwitchState = !prevSwitchState; setBusinessHours(prevHours => { if (newSwitchState) { // 开关开启:仅当不存在Sunday时添加 return prevHours.some(item => item.day === "Sunday") ? prevHours : [...prevHours, { "day": "Sunday", "open_time": "Not set", "close_time": "Not set" }]; } else { // 开关关闭:移除所有Sunday项 return prevHours.filter(item => item.day !== "Sunday"); } }); return newSwitchState; }); };
关键改进点
- 用
some(item => item.day === "Sunday")替代JSON.stringify判断,准确高效,完全依赖唯一标识day字段。 - filter时明确指定
item.day !== "Sunday",确保只操作Sunday项,不会误删其他日期。 - 函数式更新state,避免异步状态导致的逻辑错误,保证每次操作都基于最新的状态值。
内容的提问来源于stack exchange,提问作者serking
相关产品推荐
相关产品推荐

