简体   繁体   中英

React gives unique key warning for radiobutton (in map) despites unique keys being supplied

I have the following code (obviously this is just a test case for the question, life is more complicated...). This code works, but it gives the Warning:

Each child in an array or iterator should have a unique "key" prop.

I'm quite new to React and javascript, but I do understand the error , and I do understand why unique keys are needed . As you can see I am indeed providing keys and they are indeed unique

var possible_variants = ["A", "B", "C"];
var variant = "";

class App extends React.Component {
  render() {
    return React.createElement(
      "div",
      null,
      React.createElement(RadioButton, null)
    );
  }
}

class RadioButton extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    variant = event.target.value;
  }

  render() {
    return React.createElement(
      "div",
      {
        onChange: this.handleChange
      },

      possible_variants.map(function(my_variant, index) {
        return React.createElement(
          "label",
          null,
          React.createElement("input", {
            type: "radio",
            value: my_variant,
            key: my_variant,
            name: "variant"
          }),
          my_variant
        );
      })
    );
  }
}

ReactDOM.render(
  React.createElement(App, null),
  document.getElementById("container")
);

The problem seem to be that React "wants" the key be in the wrapping label instead, ie if I change the mapping to

possible_variants.map(function(my_variant, index) {
  return React.createElement(
    "label",
    {
      key: my_variant // <= here comes the difference
    },
    React.createElement("input", {
      type: "radio",
      value: my_variant,
      name: "variant"
    }),
    my_variant
  );
});

the warning goes away.

So my question is why it is so? It was my understanding from the official documentation and from various tutorials around the net that for best performance one wants the key being into the most specific thing which may change for re-rendering, and that is the input here, not the label which is fixed once and for all.

Am I missing something?

PS: To me, this feels similar to React unique key when mapping warning

First, a unique key is needed, as we both know.

As for the code, the first one actually didn't make the key binding to map items, as well as the second one, it did.

Refer to React.createElement document, each creates one level of DOM element.

In your first code, it actually created twice , which means your key only been bound inside of the map items , the map items right under list.map haven't got any keys.

<label>
  <input key={...}/>
</label>

The second one made it as normal, so it comes to the difference.

<label key={...}>
  <input />
</label>

By the way, as the comment said, you rarely have the chance to use those react top-level API , JSX/TSX just makes it simpler.

Related QA in specific.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM