2

I am using react-hook-form for the validation of my form in react.

What I am doing

  1. I have one select dropdown, which has some numbers as a dropdown.
  2. On change of select dropdown I am creating the input field, if 2 is selected then 2 input field, initially one is there by default.
  3. Now when I select 2 or 3 options and create 2-3 input fields, on click of a button it is only taking last field validation as well as giving me the last field value only.

In react-hook-form we use ref to hold the value of particular input and for validation as well.

But here it is only validating the last one only, I do not know what I am missing.

This is what I am doing.

<div className="row">
  {[...Array(inputHolder).keys()].map((li, index) => (
    <div className="col-12 col-sm-12 col-md-8 col-lg-4 col-xl-4">
      <div className="form-group">
        <input
          type="text"
          name="name"
          id={'name' + index}
          className="form-control"
          placeholder="F Name"
          ref={register({required: 'F name is required'})}
        />
        <label className="common_label_form" htmlFor={'name' + index}>
          F Name
        </label>
        {errors.name && (
          <div>
            <span className="text-danger">{errors.name.message}</span>
          </div>
        )}
      </div>
    </div>
  ))}
</div>;

This my code sandbox

I need to make my refs dynamic but I don't know how can I achieve that.

I want to have data like [{ name: 'name1' }, { name: 'name2' }], that's why I have been stuck, once I will get data then I can push it inside array.

0

2 Answers 2

2

When using form, any input elements (input, select...) inside it is identified via a name attribute, not id as you may think.

Solution 1:

map(_, index) => (
  <input
    name={`name[${index}]`}
    ref={register}
  />
)

When you log the submit data, here is what it looks like

{
  "name": ["1", "2", "3"]
}

Error displaying:

{errors.name && errors.name[index] && (
  <div>
    {errors.name[index].message}
  </div>
)}

Solution 2:

map(_, index) => (
  <input
    name={`data[${index}].name`}
    ref={register}
  />
)

Output

{
  "data": [
     { "name": "1" },
     { "name": "2" },
     { "name": "3" }
  ]
}

Error displaying

{errors.data && errors.data[index] && errors.data[index].name && (
  <div>
    {errors.data[index].name.message}
  </div>
)}

Solution 3:

map(_, index) => (
  <input
    name={`name_${index}`}
    ref={register}
  />
)

Output:

{
  "name_0": "1",
  "name_1": "2",
  "name_2": "3"
}

Error displaying:

{errors["name_" + index] && (
  <div>
    {errors["name_" + index].message}
  </div>
)}

Live Demo

Edit 64219677/how-to-validate-input-fields-in-react

Sign up to request clarification or add additional context in comments.

1 Comment

hey could you please check out this issue, it is something similar to above one, stackoverflow.com/questions/64241134/… please check what I need to do
0

I think you shoud simply change the input name li ke this

...
        <input
          type="text"
          name={'name' + index}   // you should change this
          id={'name' + index}
          className="form-control"
          placeholder="F Name"
          ref={register({required: 'F name is required'})}
        />
...

4 Comments

I tried this but this will cause issue,I need to send data in some format, that can cause issue
what kind of issue ?
first of all, I am not able to do validation by using the above approach you have shared, please check my code sandbox, to handle error I am doing like this errors.name but now as I am concatenating index, so it is throwing error errors.name+index this throws error, if this is done then also I have issue and this is main one, I have to send data like this [{ name: 'name1' }, { name: 'name1' }].. so what you are suggesting will not work for me
i extend your codesandbox codesandbox.io/s/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.