0
import { v4 as uuidv4 } from "uuid";
<form>
<div className="first-row-days">
                {["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY"].map((value) => (
                  <>
                    <input
                      type="checkbox"
                      value={value}
                      key={uuidv4()}
                      id={`${type}-${value.toLowerCase()}`}
                      onChange={(e) => setStoreDays(e)}
                    />
                    <label htmlFor={`${type}-${value.toLowerCase()}`}>
                      {value}
                    </label>
                  </>
                ))}
</div>

<div className="second-row-days">
            {["FRIDAY", "SATURDAY", "SUNDAY"].map((value) => (
              <>
                <input
                  type="checkbox"
                  value={value}
                  key={uuidv4()}
                  id={`${type}-${value.toLowerCase()}`}
                  onChange={(e) => setStoreDays(e)}
                />

                <label htmlFor={`${type}-${value.toLowerCase()}`}>
                  {value}
                </label>
              </>
            ))}
</div>
</form>

I am using uuidv4 for the input field unique key, I have even checked by passing the array index as a unique prop but I am getting the same warning by react. A similar question on StackOverflow suggests using the key on the outermost JSX tag, so I placed the key in <React.Fragment key={uuid()}> but again I get the same error(Warning: Each child in a list should have a unique "key" prop.)

  • 1
    Perhaps it’s because the key for a given item changes whenever the component is rendered. see https://stackoverflow.com/a/43892905/535480 – James Sep 22 '21 at 13:11
  • 1
    The key must be on the outermost element. For that you'll have to use the long-form `Fragment` tag. Once you move it, **please do not use a uuid generated at render time as the key!!** - this completely defeats the purpose of keys in React. You'd be better off omitting it and leaving the warning. **Again, using a uuid like this is a really really bad practice**. – Brian Thompson Sep 22 '21 at 13:31
  • Passing uuid as a key is not a good practice. on its every renders its key may change so react will consider it as a new component. and it removes the old component from the DOM and add the same one again. you can use key as some hardcoded value if it is fixed. if it is dynamic or inside some loop. then try to keep some id or index for each child – sojin Sep 22 '21 at 13:47

4 Answers4

0

After mapping set all children elements in div

<div className="second-row-days">
  {["FRIDAY", "SATURDAY", "SUNDAY"].map((value,index) => (
    <div key={uuidv4()}>
      <input
        type="checkbox"
        value={value}
        id={`${type}-${value.toLowerCase()}`}
        onChange={(e) => setStoreDays(e)}
      />
      <label
        htmlFor={`${type}-${value.toLowerCase()}`}>
        {value}
      </label>
    </div>
  ))}
</div>
IncognitoUser
  • 312
  • 1
  • 8
0

You have not assigned key to the Fragments

 {["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY"].map((value) => (
                  <Fragment key={value}> // ADD KEY HERE
                    <input/>
                    <label></label>
                  </Fragment>
                ))}

Make sure you do this for all the fragments.

PHRYTE
  • 959
  • 1
  • 9
  • 13
0

The problem is React fragment tag <></>. Modify to shorthand fragment to <React.Fragment></React.Fragment> with key property (assign unique value).The issue will be resolve.

import { v4 as uuidv4 } from "uuid";
<form>
<div className="first-row-days">
                {["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY"].map((value, index) => (
                  <React.Fragment key={"iterate-1-" + index}>
                    <input
                      type="checkbox"
                      value={value}
                      key={"first-row-days-" + index}
                      id={`${type}-${value.toLowerCase()}`}
                      onChange={(e) => setStoreDays(e)}
                    />
                    <label htmlFor={`${type}-${value.toLowerCase()}`}>
                      {value}
                    </label>
                  </React.Fragment>
                ))}
</div>

<div className="second-row-days">
            {["FRIDAY", "SATURDAY", "SUNDAY"].map((value, index) => (
               <React.Fragment key={"iterate-2-" + index}>
                <input
                  type="checkbox"
                  value={value}
                  key={"second-row-days-" + index}
                  id={`${type}-${value.toLowerCase()}`}
                  onChange={(e) => setStoreDays(e)}
                />

                <label htmlFor={`${type}-${value.toLowerCase()}`}>
                  {value}
                </label>
              </React.Fragment>
            ))}
</div>
</form>
Ganesan C
  • 269
  • 1
  • 3
  • 9
  • key={uuidv4()}. this is not a good practice. it violates all react virtual dom features and advantages . – sojin Sep 22 '21 at 13:49
-1

You can try to use value as key in your case and add <React.Fragment>.

<form>
      <div className="first-row-days">
        {["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY"].map((value) => (
          <React.Fragment key={value}>
            <input type="checkbox" value={value} />
            <label>{value}</label>
          </React.Fragment>
        ))}
      </div>

      <div className="second-row-days">
        {["FRIDAY", "SATURDAY", "SUNDAY"].map((value) => (
          <React.Fragment key={value}>
            <input type="checkbox" value={value} />
            <label>{value}</label>
          </React.Fragment>
        ))}
      </div>
    </form>