Skip to content

How to fix unique “key” prop and validateDOMNesting(…) in ReactJS with fuctional component

Hi all I have following code.

Test.js component

    const Test = ({ infoText }) => {
      return (
        <div>
          Some Text
          {infoText && <p>{infoText}</p>}
        </div>
      );
    };

export default Test;

App.js component

    export default function App() {
      return (
        <div className="App">
          <Test
            infoText={[
              <p className="someStyles">"Looking to lease multiple devices?"</p>,
              <div className="someOtherStyles">
                 <b>Get in contact with our specialist.</b>
              </div>,
            ]}
           />
         </div>
      );
    }

When I am rendering my Test component in App.js file I am getting errors like

Warning: Each child in a list should have a unique "key" prop.

Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>.

I know that is coming from this syntax that I wrote.

     infoText={[
              <p className="someStyles">"Looking to lease multiple devices?"</>,
              <div className="someOtherStyles">
                 <b>Get in contact with our specialist.</b>
              </div>,
            ]}

I need to write in this way because my Test component is reusable component and I am using it’s infoText prop for passing various tags with specific classes.

By the way, the code works. But it’s very ugly that I have so many errors in the console. Please help me fix this.

Answer

This warning is generated because usually, when a react element is an array, that array is generated dynamically, and so might change. In this scenario, you absolutely need the elements in your list to have a unique key prop to avoid unexpected behaviour from React.

In this scenario, you are absolutely fine to ignore the warnings, because your array is hardcoded, and is never going to change. If you don’t want to see these warnings, you could change the array to be a react fragment, like this:

const Test = ({ infoText }) => {
  return (
    <div>
      Some Text
      {infoText && <p>{infoText}</p>}
    </div>
  );
};

<Test
  infoText={
    <>
      <p className="someStyles">"Looking to lease multiple devices?"</p>
      <div className="someOtherStyles">
        <b>Get in contact with our specialist.</b>
      </div>
    </>
  }
/>

A more idiomatic way of achieving the same thing might be to have your Test component render its children, like this:

const Test = ({ children }) => {
  return (
    <div>
      Some Text
      <p>{children}</p>
    </div>
  );
};

<Test>
  <p className="someStyles">"Looking to lease multiple devices?"</p>
  <div className="someOtherStyles">
    <b>Get in contact with our specialist.</b>
  </div>
</Test>