Как вы знаете, вы не можете просто сделать это:
// DON'T DO THIS
{rows.map((row, index) => (
<tr key={index}>{row}</tr>
))}
Как сказано в документации , это "последнее средство" и действительно полезно только для статических списков. Вы сказали, что ваш список не будет статичным.
Довольно необычно иметь массив уже созданных подобных элементов, а не массив данных для элементов. Если бы вы могли избежать этого, я бы дал и записи данных с постоянными значениями идентификаторов, которые вы можете использовать в качестве ключей, например, (name
явно заменяет фактические данные):
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>
))}
</>
);
}
Это предполагает, что все они должны быть одного и того же типа компонента, конечно, что не может быть правдой.
Если вы не можете сделать это и должны предварительно создать фактические элементы, я бы, вероятно, создал объекты-оболочки:
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>
))}
</>
);
}
Или, если у них нет реквизита, который вам нужно указать, вы можете позволить React отслеживать их, поскольку это является частью его работы:
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>
))}
</>
);
}
Вот живой пример этого: