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

React Formik场景下handleChange内设置对象属性值的通用方法

React Formik单选框组关联对象字段的最优实现方案

该实现解决了原代码的状态冗余、逻辑硬编码问题,通用性更强,后续扩展单选选项无需修改处理逻辑。

核心优化思路

  • 移除组件内部冗余的单选选中状态,直接以Formik values中的值作为唯一数据源,避免双向状态不同步
  • 抽象单选组更新逻辑,无需硬编码对应字段名,适配任意数量的同组单选框
  • 保留原对象中的日期等其他字段不被覆盖,符合需求

优化后完整代码

import React, {Component} from 'react';
import {Col, Row} from 'react-bootstrap';
import Radio from "./radio";

export default class EventTimeFrame extends Component {
    // 单选选项仅存静态配置,checked状态直接从Formik取值
    state = {
        eventTimeFrame: [
            {id: 1, value: "one_off", label: "ONE OFF"},
            {id: 2, value: "recurring", label: "RECURRING"},
        ]
    }

    handleOccurance = e => {
        const selectedValue = e.target.value;
        // 复制原time_frame对象,保留已有日期等其他字段
        const updatedTimeFrame = {...this.props.values.time_frame};
        
        // 遍历所有单选选项批量设为false,无需硬编码字段名
        this.state.eventTimeFrame.forEach(item => {
            updatedTimeFrame[item.value] = false;
        });
        // 当前选中项设为true
        updatedTimeFrame[selectedValue] = true;

        this.props.onChange("time_frame", updatedTimeFrame);
    };

    handleTime = e => {
        const updatedTimeFrame = {
            ...this.props.values.time_frame,
            start: new Date(e.target.value)
        };
        this.props.onChange("time_frame", updatedTimeFrame);
    };

    render() {
        const { time_frame } = this.props.values;
        return (
            <div>
                <Row>
                    <Col>
                        <h4 className="ui centered question-header text-center">ONE OFF OR RECURRING EVENT?</h4>
                    </Col>
                </Row>
                <Row>
                    {
                        this.state.eventTimeFrame.map((timeFrame) => {
                            return (
                                <Radio 
                                    name="time_frame" 
                                    key={timeFrame.value}
                                    onChange={this.handleOccurance} 
                                    // 直接从Formik values取选中状态,无冗余维护成本
                                    checked={!!time_frame?.[timeFrame.value]} 
                                    {...timeFrame} 
                                />
                            )
                        })
                    }
                </Row>
                <Row>
                    <Col>
                        <h4 className="question-header date-text">PLEASE ENTER THE FIRST DAY OF YOUR EVENT</h4>
                    </Col>
                    <Col>
                        <input 
                            type="date" 
                            className="form-control date" 
                            name="start"
                            // 补全受控组件value属性,避免显示和存储值不同步
                            value={time_frame?.start ? new Date(time_frame.start).toISOString().split('T')[0] : ''}
                            onChange={this.handleTime}
                        />
                    </Col>
                </Row>
            </div>
        )
    }
}

关键优化说明

  1. 移除了state中eventTimeFrame的checked属性,以Formik values作为唯一可信数据源,无需额外做状态同步
  2. handleOccurance逻辑完全通用,后续新增单选选项只需修改eventTimeFrame配置数组即可,无需调整处理函数
  3. 利用单选框互斥特性,无需额外判断checked属性,触发onChange即为选中状态
  4. 增加可选链判断和date输入框的value绑定,避免time_frame未初始化时报错,符合React受控组件规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:21:01