Reputation: 348
I am trying to implement a functional component in my react app: https://gist.github.com/andreisamoila74/bca55271c3992c079eed018e5c95a1be And these are the warnings:
Warning: Each child in a list should have a unique "key" prop.
Check the render method of `ViewCode`
in Fragment
in ViewCode (at App.js:87)
in Route (at App.js:86)
in Switch (at App.js:72)
in main (created by Basic)
in Basic (created by Context.Consumer)
in Content (at App.js:71)
in section (created by Context.Consumer)
in BasicLayout (created by Context.Consumer)
in Layout (at App.js:68)
in App (at src/index.js:13)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.js:12)
in Suspense (at src/index.js:11)
Warning: validateDOMNesting(...): <tr> cannot appear as a child of <div>.
in tr (at View.js:49)
in div (at View.js:48)
in tbody (at View.js:93)
in table (at View.js:92)
in section (created by Context.Consumer)
in BasicLayout (created by Context.Consumer)
in Layout (at View.js:91)
in div (at View.js:90)
in ViewCode (at App.js:87)
in Route (at App.js:86)
in Switch (at App.js:72)
in main (created by Basic)
in Basic (created by Context.Consumer)
in Content (at App.js:71)
in section (created by Context.Consumer)
in BasicLayout (created by Context.Consumer)
in Layout (at App.js:68)
in App (at src/index.js:13)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.js:12)
in Suspense (at src/index.js:11)
Warning: validateDOMNesting(...): <div> cannot appear as a child of <tbody>.
in div (at View.js:48)
in tbody (at View.js:93)
in table (at View.js:92)
in section (created by Context.Consumer)
in BasicLayout (created by Context.Consumer)
in Layout (at View.js:91)
in div (at View.js:90)
in ViewCode (at App.js:87)
in Route (at App.js:86)
in Switch (at App.js:72)
in main (created by Basic)
in Basic (created by Context.Consumer)
in Content (at App.js:71)
in section (created by Context.Consumer)
in BasicLayout (created by Context.Consumer)
in Layout (at App.js:68)
in App (at src/index.js:13)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.js:12)
in Suspense (at src/index.js:11)
I understand each warning, but I am not sure how I can get rid of its. Regarding the table, I need those divs so my AddComment component is placed in the right way. How should I solve this? Thanks :)
Upvotes: 1
Views: 623
Reputation: 348
I solved it this way:
rows.push(
<React.Fragment key={index}>
<tr key={index} className="line">
<td className="line-number">{index + 1}</td>
<td id={"plus" + index} className="plus-square-line">
<PlusSquareTwoTone className="plus-square"
onClick={() => toggleLineCommentStatus(index + 1)} />
</td>
<td id={"codeblock" + index}
className={'language-' + codeLanguage} style={rowStyle}>
{line}
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>
{lineComments[index + 1]
?
<AddComment
id={id}
lineNumber={index + 1}
onCancelLineCommentShow={toggleLineCommentStatus}
/>
:
null
}
</td>
</tr>
</React.Fragment>
);
thanks for answers
Upvotes: 0
Reputation: 202721
The react keys need to be declared on the outer-most element mapped. In your case, the Fragment
, or rather, the div
since the Fragment
isn't doing much for you.
The second error: "validateDOMNesting(...): cannot appear as a child of " is saying the tr
can't be a child of the div
.
You can still use a Fragment
though for both the purpose of returning a single node and provide the react key.
data.code.source_code.split("\n").forEach((line, index) => {
rows.push(
<Fragment key={index}> // <-- attach react key to Fragment
<tr className="line">
<td className="line-number">{index + 1}</td>
<td id={"plus" + index} className="plus-square-line">
<PlusSquareTwoTone
className="plus-square"
onClick={() => toggleLineCommentStatus(index + 1)}
/>
</td>
<td
id={"codeblock" + index}
className={"language-" + codeLanguage}
style={rowStyle}
>
{line}
</td>
</tr>
<div style={divStyle}>
{lineComments[index + 1] ? (
<AddComment
id={id}
lineNumber={index + 1}
onCancelLineCommentShow={toggleLineCommentStatus}
/>
) : null}
</div>
</Fragment>
);
});
Upvotes: 1
Reputation: 2923
When you create an array of children, like on row 46, each of them need to have a key
prop.
If you don't have it, there is no way for React to know how the new and the old arrays are different, so it has to rerender all children, which is a performance drag. With key
prop, it checks for new or deleted children by comparing keys from the new and old arrays of children.
You can read about it here https://kentcdodds.com/blog/understanding-reacts-key-prop
Upvotes: 0