1

I am rendering a form based on what fields are available in selectedAddress. The key variables are all unique but I am seeing a each child in a list must have a unique key error, and the validation is not working. What am I missing?

import { useForm } from "react-hook-form";

const {
  register,
  handleSubmit,
  formState: { errors },
  } = useForm();

const RenderSelectedAddress = () => {
if (selectedAddress && !editAutocompletedForm) {

  const entries = Object.entries(selectedAddress);

  const formEntries = entries.map(([key, value]) => (
    <>
      <label htmlFor={key}>{key}</label>
      <input
        defaultValue={value}
        type="text"
        placeholder="Placeholder"
        id={key}
        {...register( key , { required: "required" })}
      ></input>
      {errors.key && <p>{errors.key.message}</p>}
    </>
  ));

  return formEntries;

}

return null;

};

2 Answers 2

1
  1. key prop should be on the first child of the rendered list. In your case, you used a fragment which doesn't accept a key prop in the shortened form. Instead of <>...</> use: <React.Fragment key={key}></React.Fragment>.

  2. For the validation error, I beilieve it's the fact that you access the errors incorrectly. Instead of errors.key, use errors[key].

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

2 Comments

Thanks for the quick answer, this sorted it.. Just wondering r.e #2 This syntax works in another form I am using: {errors.email ? <div>{errors.email.message}</div> : null}. Why are square brackets needed when using an array?
That's because here your values are dynamic, meaning that accessing errors.key will try to look for a key, with the name key inside errors, while errors[key] will access the value of the current key in the loop inside errors
1

Every time you do a map, you need to attribute a key attribute with a unique value to what is being rendered. In this case, you should use divs instead of React.Fragment and give it a key...

const formEntries = entries.map(([key, value]) => (
    <div key={value}>
      <label htmlFor={key}>{key}</label>
      <input
        defaultValue={value}
        type="text"
        placeholder="Placeholder"
        id={key}
        {...register( key , { required: "required" })}
      ></input>
      {errors.key && <p>{errors.key.message}</p>}
    </div>
  ));

this is not mandatory, and you get those warnings, but it's very important for React to optimize rendering. Also, the value of key should be a string, not an object.

Please read the docs, pertaining this subject: https://reactjs.org/docs/lists-and-keys.html

Comments

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.