I would like to add a unique key to the returned elements this function provides.
function RowList() {
const rows = [<Row0 />, <Row1 />, <Row2 />, <Row3 />];
return (
<>
{rows.map(row => (
<tr key={?}>{row}</tr>
))}
</>
);
}
I have tried:
function Rows() {
const rows = [<Row0 />, <Row1 />, <Row2 />, <Row3 />];
return (
<>
{rows.map(row => (
<tr key={row}>{row}</tr>
))}
</>
);
}
But [object Object]
is returned as the key.
I also will not be able to do something like
let x = 0
function Rows() {
const rows = [<Row0 />, <Row1 />, <Row2 />, <Row3 />];
return (
<>
{rows.map(row => (
<tr key={x = x + 1}>{row}</tr>
))}
</>
);
}
As I will need to be able to remove and add back to the array later.
As you know, you can't just do this:
// DON'T DO THIS
{rows.map((row, index) => (
<tr key={index}>{row}</tr>
))}
As the documentation says, that's a "last resort" and really only useful for static lists. You've said your list won't be static.
It's fairly unusual to have an array of already-created elements like that rather than an array of the data for the elements. If you can avoid it, I would, and give the data entries enduring ID values that you can use as keys, eg ( name
is obviously a stand-in for actual data):
class RowInfo {
static id = 0;
constructor(name) {
this.name = name;
this.id = RowInfo.id++;
}
}
function RowList() {
const rows = [new RowInfo("one"), new RowInfo("two"), new RowInfo("three"), new RowInfo("four")];
return (
<>
{rows.map(({id, name}) => (
<tr key={id}><Row name={name}/></tr>
))}
</>
);
}
That assumes that they should all be the same type of component, of course, which may not be true.
If you can't do that and must pre-create the actual elements, I'd probably create wrapper objects:
class RowInfo {
static id = 0;
constructor(element) {
this.element = element;
this.id = RowInfo.id++;
}
}
function RowList() {
const rows = [new RowInfo(<Row0 />), new RowInfo(<Row1 />), new RowInfo(<Row2 />), new RowInfo(<Row3 />)];
return (
<>
{rows.map(({id, element}) => (
<tr key={id}>{element}</tr>
))}
</>
);
}
Or if they don't have any props you need to specify, you can let React keep track of them, as that's part of its job:
class RowInfo {
static id = 0;
constructor(Comp) {
this.Comp = Comp;
this.id = RowInfo.id++;
}
}
function RowList() {
const rows = [new RowInfo(Row0), new RowInfo(Row1), new RowInfo(Row2), new RowInfo(Row3)];
return (
<>
{rows.map(({id, Comp}) => (
<tr key={id}><Comp/></tr>
))}
</>
);
}
Here's a live example of that one:
const Row0 = () => <div>Row 0</div>; const Row1 = () => <div>Row 1</div>; const Row2 = () => <div>Row 2</div>; const Row3 = () => <div>Row 3</div>; const {Fragment} = React; class RowInfo { static id = 0; constructor(Comp) { this.Comp = Comp; this.id = RowInfo.id++; } } // Have to use <Fragment></Fragment> in the below instead of <></> because // Stack Snippet's version of Babel is out of date and // doesn't understand <></>. function RowList() { const rows = [new RowInfo(Row0), new RowInfo(Row1), new RowInfo(Row2), new RowInfo(Row3)]; return ( <Fragment> {rows.map(({id, Comp}) => ( <tr key={id}><Comp/></tr> ))} </Fragment> ); } ReactDOM.render(<RowList/>, document.getElementById("root"));
<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
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.