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

自定义Formik二维码读取按钮触发无值表单提交问题

问题解决:Formik中二维码按钮触发表单提交+值无法传入的修复

问题分析

  1. 触发表单提交:尽管按钮设置了type="button",事件冒泡仍可能触发Form的submit事件;
  2. 值无法传入:当前setQrData仅做日志输出,未调用Formik的字段更新方法,无法将二维码数据同步到对应表单字段。

修复方案

1. 阻止事件冒泡,避免误触提交

修改QrReaderButton.tsx,在按钮点击事件中添加阻止冒泡逻辑:

import { useState } from "react";
import { QrReader } from "react-qr-reader";
import qrcode from "../assets/qr-code.png";
interface Props {
  setQrData: (data: any) => void;
}

const QrReaderButton: React.FC<Props> = (props) => {
  const [data, setData] = useState<any>();
  const [show, setShow] = useState<boolean>(false);

  const toggleReader = (e: React.MouseEvent<HTMLButtonElement>) => {
    // 阻止事件冒泡,避免触发表单提交
    e.stopPropagation();
    setShow(!show);
  };

  return (
    <div className="flex flex-col w-max items-center">
      <button
        type="button"
        onClick={toggleReader}
      >
        <img src={qrcode} alt="qr-code" width={40} />
      </button>
      {show && (
        <div className="w-96">
          <QrReader
            onResult={(result: any, error) => {
              if (!!result) {
                const parsedData = JSON.parse(result?.text);
                setData(parsedData);
                props.setQrData(parsedData);
              }
              if (!!error) {
                // console.info(error);
              }
            }}
            constraints={{ facingMode: "user" }}
          />
          <p> {data ? JSON.stringify(data) : "No result"}</p>
        </div>
      )}
    </div>
  );
};

export default QrReaderButton;

2. 同步二维码数据到Formik字段

修改CustomTextInput.tsx,获取Formik的setFieldValue方法,将二维码数据更新到当前表单字段:

import {
  FormControl,
  FormHelperText,
  FormLabel,
  Input,
} from "@chakra-ui/react";
import QrReaderButton from "../QrReaderButton";

const CustomTextInput = ({
  field,
  form: { touched, errors, setFieldValue },
  ...props
}: any) => {
  const handleQrData = (data: any) => {
    // 将二维码数据同步到当前Formik字段
    setFieldValue(field.name, data);
  };

  return (
    <FormControl isInvalid={errors[field.name] && touched[field.name]}>
      <FormLabel>{props.label}</FormLabel>
      <div className="flex gap-2">
        <Input {...field} {...props} />
        <div className="w-max">
          <QrReaderButton setQrData={handleQrData} />
        </div>
      </div>
      <FormHelperText>this is helper</FormHelperText>
    </FormControl>
  );
};

export default CustomTextInput;

额外优化点

  • 修正FormControl的isInvalid判断逻辑,适配动态字段名;
  • 明确setQrData的类型定义,提升代码严谨性;
  • 提取点击事件函数,使代码结构更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:25:16