如何使用react-hook-form渲染带有零数组的表单?

问题描述 投票:0回答:2

我有一个基本表单,其代码使用

react-hook-form
,看起来像:

import "./styles.css";
import { useForm, useFieldArray, Control, Controller } from 'react-hook-form';
import { useState } from 'react';

const defaultValues = {
  "foo": [
    {
      "bar": [0, 0, 0]
    },
    {
      "bar": [4, 5, 6]
    }
  ]
}


const FooComponent = ({fooIndex, control}) => {
  const { fields, append, remove } = useFieldArray({
    control,
    name: `foo.${fooIndex}.bar`,
    keyName: 'id'
  });

  return (
    <div>
      <h1>Foo</h1>
      {fields.map((field, index) => (
        <Controller
          key={field.id}
          name={`foo.${fooIndex}.bar.${index}`}
          control={control}
          defaultValue={String(field.value)} // Convert to string
          render={({field}) => (
            <input {...field} value={String(field.value)} /> // Ensure the value is a string
          )}
        />
      ))}
    </div>
  )
};


export default function App() {
  const { control, handleSubmit, getValues } = useForm({
    defaultValues
  });
  const [formValue, setFormValue] = useState(null);

  const { fields, append, remove } = useFieldArray({
    control,
    name: 'foo',
    keyName: 'id'
  });

  const onSubmit = async () => {

  };

  const handlePrintForm = () => {
    setFormValue(getValues())
  };

  return (
    <div className="App">
      <div>
        <h1>Form value:</h1>
        <p>{JSON.stringify(formValue, null, 2)}</p>
      </div>
      <form onSubmit={handleSubmit(onSubmit)}>
        {fields.map((field, index) => (
          <div key={field.id}>
            <FooComponent fooIndex={index} control={control}/>
          </div>
        ))}
        <button onClick={(()=>append({'bar': [1, 2, 3]}))}>Add Foo</button>
      </form>
      <button onClick={handlePrintForm}>Print form</button>
    </div>
  );
}

当数组中包含零值时,表单会显示数组中零的数量,少于应有的数量。例如,对于全零的数组,不会显示任何内容:

zero values not rendereing

而带有

[0, 1, 2]
的数组:

enter image description here

我该如何解决这个问题?

codesandbox 链接

javascript reactjs react-hook-form
2个回答
0
投票

我对代码进行了以下更改

  1. 使用对象数组而不仅仅是基元。
  2. 删除字符串强制并用
    toString()
    方法替换 JSON.stringify。

现在应该可以了。

import "./styles.css";
import { useForm, useFieldArray, Control, Controller } from "react-hook-form";
import { useState } from "react";

const defaultValues = {
  foo: [
    {
      bar: [{ data: 0 }, { data: 0 }, { data: 0 }],
    },
    {
      bar: [{ data: 4 }, { data: 5 }, { data: 6 }],
    },
  ],
};

const FooComponent = ({ fooIndex, control }) => {
  const { fields, append, remove } = useFieldArray({
    control,
    name: `foo.${fooIndex}.bar`,
    keyName: "id",
  });

  return (
    <div>
      <h1>Foo</h1>
      {fields.map((field, index) => (
        <Controller
          key={field.id}
          name={`foo.${fooIndex}.bar.${index}.data`}
          control={control}
          defaultValue={field.data}
          render={({ field }) => (
            <input {...field} value={field.value.toString()} /> // Ensure the value is a string
          )}
        />
      ))}
    </div>
  );
};

export default function App() {
  const { control, handleSubmit, getValues } = useForm({
    defaultValues,
    shouldUnregister: false,
  });
  const [formValue, setFormValue] = useState(null);

  const { fields, append, remove } = useFieldArray({
    control,
    name: "foo",
    keyName: "id",
  });

  const onSubmit = async () => {};

  const handlePrintForm = () => {
    setFormValue(getValues());
  };

  return (
    <div className="App">
      <div>
        <h1>Form value:</h1>
        <p>{JSON.stringify(formValue, null, 2)}</p>
      </div>
      <form onSubmit={handleSubmit(onSubmit)}>
        {fields.map((field, index) => (
          <div key={field.id}>
            <FooComponent fooIndex={index} control={control} />
          </div>
        ))}
        <button onClick={() => append({ bar: [1, 2, 3] })}>Add Foo</button>
      </form>
      <button onClick={handlePrintForm}>Print form</button>
    </div>
  );
}

0
投票

iniubong Obonguko 提供的解决方案或多或少是正确的,因为字段数组必须是对象数组才能使

useFieldArray
正常运行。

您可以在他们的官方文档中通过检查

fields
的类型和所有与数组相关的函数的参数类型来验证这一点(请参阅 useFieldArray > Return > fields): Definition of type of fields

对上述解决方案进行一些小修正:

  • 无需删除字符串强制,您可以继续使用
    String(field.value)
  • append({ bar: [1, 2, 3] })
    应更新为
    append({ bar: [{ field: 1 }, { field: 2 }, { field: 3 }] })
    (您可以使用任何名称代替
    field
    )。
  • 您可以删除
    keyName
    ,因为它将在下一个主要版本中删除(请参阅 useFieldArray > Props > keyName)。

工作CodeSandbox:https://codesandbox.io/p/sandbox/happy-bouman-8m8sjm?file=%2Fsrc%2FApp.js%3A1%2C1-81%2C1

© www.soinside.com 2019 - 2024. All rights reserved.