使用复选框在 ReactJS 中保存表单值

2023-12-03

我使用反应钩子表单创建了一个表单组件。该组件由一组复选框和一个文本输入组成。当用户单击最后一个复选框时出现文本输入custom。这个的想法是:当用户单击时,会出现一个文本输入,并且用户可以添加自定义答案/选项。例如:如果用户输入test在输入中,然后当用户保存表单时,应该出现在数组中test值,但是custom文本不应该在数组中。在我的应用程序中我无权访问const onSubmit = (data) => console.log(data, "submit");,所以我需要更改其中的值Component成分。现在,当我点击提交时,我进入了最终的数组custom value.
问题:如何解决上述问题?

const ITEMS = [
  { id: "one", value: 1 },
  { id: "two", value: 2 },
  { id: "Custom Value", value: "custom" }
];

export default function App() {
  const name = "group";
  const methods = useForm();
  const onSubmit = (data) => console.log(data, "submit");

  return (
    <div className="App">
      <FormProvider {...methods}>
        <form onSubmit={methods.handleSubmit(onSubmit)}>
          <Component ITEMS={ITEMS} name={name} />
          <input type="submit" />
        </form>
      </FormProvider>
    </div>
  );
}
export const Component = ({ name, ITEMS }) => {
  const { control, getValues } = useFormContext();
  const [state, setState] = useState(false);

  const handleCheck = (val) => {
    const { [name]: ids } = getValues();

    const response = ids?.includes(val)
      ? ids?.filter((id) => id !== val)
      : [...(ids ?? []), val];

    return response;
  };

  return (
    <Controller
      name={name}
      control={control}
      render={({ field, formState }) => {
        return (
          <>
            {ITEMS.map((item, index) => {
              return (
                <>
                  <label>
                    {item.id}
                    <input
                      type="checkbox"
                      name={`${name}[${index}]`}
                      onChange={(e) => {
                        field.onChange(handleCheck(e.target.value));
                        if (index === ITEMS.length - 1) {
                          setState(e.target.checked);
                        }
                      }}
                      value={item.value}
                    />
                  </label>
                  {state && index === ITEMS.length - 1 && (
                    <input
                      {...control.register(`${name}[${index}]`)}
                      type="text"
                    />
                  )}
                </>
              );
            })}
          </>
        );
      }}
    />
  );
};


demo: https://codesandbox.io/s/winter-brook-sml0ww?file=/src/Component.js:151-1600


假设目标是使所有选择保持相同group字段,它必须是一个按提供的顺序记录所选值的数组,如果指定,则将自定义输入值作为最后一项,也许理想情况下,计算中的值会更容易onSubmit提交之前。

但由于偏好不添加逻辑onSubmit,也许另一种选择是托管本地状态,在状态发生变化时运行所需的计算,然后调用setValue手动将计算值同步到group field.

经过修改的分叉演示:代码沙箱

import "./styles.css";
import { Controller, useFormContext } from "react-hook-form";
import React, { useState, useEffect } from "react";

export const Component = ({ name, ITEMS }) => {
  const { control, setValue } = useFormContext();
  const [state, setState] = useState({});

  useEffect(() => {
    const { custom, ...items } = state;
    const newItems = Object.entries(items).filter((item) => !!item[1]);
    newItems.sort((a, b) => a[0] - b[0]);
    const newValues = newItems.map((item) => item[1]);
    if (custom) {
      setValue(name, [...newValues, custom]);
      return;
    }
    setValue(name, [...newValues]);
  }, [name, state, setValue]);

  const handleCheck = (val, idx) => {
    setState((prev) =>
      prev[idx] ? { ...prev, [idx]: null } : { ...prev, [idx]: val }
    );
  };

  const handleCheckCustom = (checked) =>
    setState((prev) =>
      checked ? { ...prev, custom: "" } : { ...prev, custom: null }
    );

  const handleInputChange = (e) => {
    setState((prev) => ({ ...prev, custom: e.target.value }));
  };

  return (
    <Controller
      name={name}
      control={control}
      render={({ field, formState }) => {
        return (
          <>
            {ITEMS.map((item, index) => {
              const isCustomField = index === ITEMS.length - 1;
              return (
                <React.Fragment key={index}>
                  <label>
                    {item.id}
                    <input
                      type="checkbox"
                      name={name}
                      onChange={(e) =>
                        isCustomField
                          ? handleCheckCustom(e.target.checked)
                          : handleCheck(e.target.value, index)
                      }
                      value={item.value}
                    />
                  </label>
                  {typeof state["custom"] === "string" && isCustomField && (
                    <input onChange={handleInputChange} type="text" />
                  )}
                </React.Fragment>
              );
            })}
          </>
        );
      }}
    />
  );
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用复选框在 ReactJS 中保存表单值 的相关文章

随机推荐

  • 如何将对象解构为已定义的变量? [复制]

    这个问题在这里已经有答案了 以下产生语法错误 let source screenings size source screenings a size b screenings size source 预期结果 screenings shou
  • Javascript 日期在 iOS 上无效

    我正在开发一个基于 Phonegap 的 iOS 应用程序 该应用程序已经为 Android 做好了 以下几行适用于 Android 但不适用于 iOS 为什么 var d new Date 2015 12 31 00 00 00 cons
  • 自定义 Woocommerce 店面主页上显示的产品

    我已经绞尽脑汁思考了太久 但找不到解决方案 我尝试过使用插件来连接 woo 商务文档和店面文档 但没有成功 默认情况下 主题有 新品 和 畅销商品 其中列出了 4 个 新品 和 4 个 畅销商品 我想将 4 个 新产品 增加到 8 个 即
  • 图标题 学名 + textGrob gtable 中的符号

    首先 我要感谢 Baptiste 爵士帮助我改进 R 脚本 使用 gtable textGrob 在组合图的左下角添加标题 如下所示 library grid library gridExtra library ggplot2 p1 lt
  • Apache+PHP 在unix上的写权限

    我正在尝试在 Fedora 上使用 apache 启动 PHP 站点 但遇到了写入权限问题 看起来 apache 对某些文件夹没有写权限 但我不明白为什么 我检查了httpd conf 它有组 apache 用户 apache 然后我做了
  • 在 Google 地图中创建自定义信息窗口

    我需要为 Google 地图信息窗口创建自定义外观 直边框架和透明度等 我知道这只能通过外部插件来实现 但我不确定该使用哪一个 我尝试过使用 extInfoWindow 但在使其正常工作时遇到问题 我还查看了 PD 标记窗口 http ww
  • 提交按钮未提交

    div class buttons div
  • 将指定内容作为属性的 XML 导入到 MySQL 表中?

    我有一个如下所示的 XML 文件
  • 将多个json反序列化为对象c#

    我正在尝试从具有多个对象的 API 调用中反序列化 json 字符串 但没有取得太大成功 JSON purchaseOrders supplierId 500 currencyCode EUR companyId LALA companyN
  • 使用虚方法的 C++ 对象大小

    我对虚拟对象的大小有一些疑问 1 虚函数 class A public int a virtual void v A类的大小是8字节 一个整数 4字节 加1个虚拟指针 4字节 天气晴朗 class B public A public int
  • Bullet/ammo.js 中的刚体(形状)来自 Three.js 中的网格

    我将bullet ammo js 与 Three js 一起使用 我有一个 3d 网格 我想使用精确的形状与软体进行碰撞检测 有没有办法从网格 在 Three js 中 创建 3D 刚体 在项目符号中 这是一个例子 http kidzins
  • 对子数组进行向量化 numpy 唯一

    我有一个形状为 N 20 20 的 numpy 数组数据 其中 N 是一个非常大的数字 我想获取每个 20x20 子数组中唯一值的数量 循环如下 values for i in data values append len np uniqu
  • 为什么java支持原始数据类型的函数重载? [复制]

    这个问题在这里已经有答案了 在学习java中的自动装箱和拆箱时 我了解到java会在需要时将原始数据类型转换为包装类 反之亦然 例如如果函数正在执行Integer作为参数 如果我们将值传递为1然后java编译器会将其转换为new Integ
  • 内存中、独立、断开连接的 ADO 记录集

    当我的表单加载时 我在数据表子表单上运行此代码 并且没有收到任何错误消息或代码中断 我的 debug print 显示记录集 rs 充满了 2131 条记录 就像它应该的那样 但我的表单显示单行带有 Name 在各个领域 我的控件上的控件源
  • 在Android中浏览并上传pdf或word文件

    private void getDocument Intent intent new Intent Intent ACTION GET CONTENT intent setType application msword applicatio
  • ASP.Net MVC4 将“创建视图”绑定到包含列表的模型

    你好 在互联网领域 我有一个有趣的难题要问你 如果该对象包含纯粹使用 MVC 视图 部分视图的其他对象的列表 是否可以绑定视图来创建对象 伙计 结果很复杂 就像 让我给你一个快速的代码示例来说明我的意思 Models public clas
  • mongodb是否会自动在嵌入文档的_id字段上创建索引?

    在 node js 项目上使用 mongodb 和 mongoose 我想知道是否必须在嵌入项目的 id 字段上确保索引 也就是说 我看到 mongodb 自动在集合的 id 字段上创建索引 它是否也对嵌入集合的 id 字段执行相同的操作
  • 使用反射在抽象类中创建实例

    是否可以使用反射在抽象祖先类中创建派生类的实例 可以说 abstract class Base public Base createInstance using reflection Class ctor c getConstructor
  • Google 日历 api(超出日历使用限制)

    我在我的 php 项目中使用 Google Calendar Api 每天在执行插入查询时都会收到 超出日历使用限制 消息 但删除和列表方法工作正常 这是我的插入功能 谁能帮我 function insertEvent start end
  • 使用复选框在 ReactJS 中保存表单值

    我使用反应钩子表单创建了一个表单组件 该组件由一组复选框和一个文本输入组成 当用户单击最后一个复选框时出现文本输入custom 这个的想法是 当用户单击时 会出现一个文本输入 并且用户可以添加自定义答案 选项 例如 如果用户输入test在输