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

ReactJS中勾选复选框时更新Formik表单值的问题

解决Formik表单中勾选同地址时同步收货地址到账单地址的问题

核心思路

要解决这个问题,需同时处理三个关键点:

  • 勾选复选框时自动复制收货地址到账单地址
  • 先勾选复选框再填写收货地址时,账单地址能同步更新
  • 调整验证规则,避免勾选时账单地址的必填验证报错

具体实现步骤

1. 调整Yup验证规则

使用Yup的when方法,根据复选框状态动态控制账单地址的必填规则:当勾选"同地址"时,账单地址无需必填;未勾选时保持必填要求。

2. 处理复选框的 onChange 逻辑

结合Formik提供的handleChange和setFieldValue,在勾选复选框时复制收货地址到账单地址,取消勾选时可选择清空账单地址。

3. 监听收货地址变化,同步更新账单地址

使用useEffect监听收货地址和复选框状态,当勾选状态下收货地址更新时,自动同步账单地址,解决先勾选再填收货地址的场景。

修改后的完整代码

import { useEffect } from 'react';
import { Formik, Form } from 'formik';
import * as yup from 'yup';

const DetailsPage = () => {
  return (
    <Formik
      initialValues={{
        name_s: "",
        name_b: "",
        same_address_box: false,
      }}
      validationSchema={yup.object({
        name_s: yup.string().required("Required"),
        // 根据复选框状态动态控制账单地址的必填规则
        name_b: yup.string().when('same_address_box', {
          is: false,
          then: yup.string().required("Required"),
          otherwise: yup.string().notRequired()
        })
      })}
      onSubmit={(values, { setSubmitting }) => {
        setTimeout(() => {
          updateOrderInfo("name_s", values.name_s);
          updateOrderInfo("name_b", values.name_b);
          setSubmitting(false);
        }, 500);
      }}
    >
      {({ values, setFieldValue, handleChange }) => {
        // 监听收货地址和复选框状态,同步更新账单地址
        useEffect(() => {
          if (values.same_address_box) {
            setFieldValue('name_b', values.name_s);
          }
        }, [values.name_s, values.same_address_box, setFieldValue]);

        return (
          <Form>
            <section id="shipping-details-container">
              <MyTextInput
                name="name_s"
                type="text"
                placeholder="Shipping name..."
              />
            </section>

            <section id="billing-details-container">
              <MyCheckbox 
                name="same_address_box"
                onChange={(e) => {
                  // 先让Formik处理默认的字段更新
                  handleChange(e);
                  const isChecked = e.target.checked;
                  // 勾选时复制收货地址,取消时清空账单地址
                  setFieldValue('name_b', isChecked ? values.name_s : '');
                }}
              >
                Same Address
              </MyCheckbox>
              {/* 直接用布尔值判断,无需转字符串 */}
              {!values.same_address_box && (
                <div id="hide-address-container">
                  <MyTextInput
                    name="name_b"
                    type="text"
                    placeholder="Billing name..."
                  />
                </div>
              )}
            </section>

            <button type="submit">Submit</button>
          </Form>
        );
      }}
    </Formik>
  );
};

关键细节说明

  • 验证规则调整:通过yup.when实现条件验证,避免勾选时账单地址的必填报错。
  • 复选框 onChange:先调用Formik的handleChange维护字段状态,再执行地址复制逻辑,不破坏Formik的默认行为。
  • 同步更新逻辑:useEffect监听收货地址和复选框状态,确保任何场景下勾选状态的账单地址都与收货地址保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:40:47