javascriptreactjsreact-functional-component

How to pass key to React functional component inside .map()?


I have faced a typical problem of React must be having 'key prop for each child' inside .map() method.

I have tried to make a key inside a functional component, like...

export default function FunctionalComponent({ title, parentDashedTitle }) {
    const dashedTitle = title.split(' ').join('-');

    return <div
    key={`${dashedTitle}-in-${parentDashedTitle}`}
    >
        {title}
    </div>
}

But it didn't work. I have found that React requires the 'key' prop to be pointed inside the .map() method's function itself, but any time I try to put 'key' prop inside functional component, like...

//Parent.js
export default function ParentComponent({ bigTitle, titles }) {
    const parentDashedTitle = bigTitle.split(' ').join('-');

    return <>
        {
            titles.map(title => {
                const dashedTitle = title.split(' ').join('-');

                return <FunctionalComponent
                key={`${dashedTitle}-in-${parentDashedTitle}`}
                title={title}
                parentDashedTitle={parentDashedTitle}
                />
            })
        }
    </>
}

//Child.js
export default function FunctionalComponent({ title, key }) {
    return <div key={key}>
        {title}
    </div>
}

but it doesn't work either and returns an error of "key is not a prop and will return undefined if it's called". Is there any solution to this problem? Do you have any suggestions? It doesn't affect work or appearance of my website, but I want this error to be gone. If it helps, I test it in Safari.


Solution

  • One way around this is to use the React Fragment which allows for props like the key and adds no extra element to the DOM. Note that the keys should also be unique.

    import { Fragment } from "react";
    
    //Parent.js
    export default function ParentComponent({ bigTitle, titles }) {
      const parentDashedTitle = bigTitle.split(" ").join("-");
    
      return (
          titles.map((title) => {
            const dashedTitle = title.split(" ").join("-");
    
            return (
              <Fragment key={`${dashedTitle}-in-${parentDashedTitle}`}> //Pass the key here instead
                <FunctionalComponent
                  title={title}
                />
              </Fragment>
            );
          })
      );
    }
    
    
    //Child.js
    export default function FunctionalComponent({ title }) {
        return <div>
            {title}
        </div>
    }