2017-12-20 13 views
0

I die folgenden verschachtelten Komponenten:Eingebettete Ausdruck als Array statt der einzelnen Elemente Rendering

<Table data={records}> 
    <TableColumn field="code">Code</TableColumn> 
    {columns.map((column, i) => (
     <TableColumn key={column} field={column}> 
     {column} 
     </TableColumn> 
    ))} 
</Table> 

My Table Komponente erweitert diese Schnittstelle:

export interface TableProps { 
    data: any[]; 
    children: React.ReactElement<TableColumnProps>[]; 
} 

dass die Komponente, I Schleife durch die Kinder (Instanzen von TableColumn) der Table mit der folgenden Funktion:

getDefaultSortColumn() { 
    let col = this.props.children[0].props.field; 
    this.props.children.forEach((column: React.ReactElement<TableColumnProps>) => { 
     if (column.props.sortDefault) { 
     col = column.props.field; 
     } 
    }); 
    return col as string; 
    } 

Wenn dies ausgeführt wird, ist meine Erwartung, dass der JSX-Ausdruck mit map() ausgeführt wurde und, wenn es 4 Elemente in columns gibt, werden 5 TableColumn Elemente als direkte Kinder in meinem Table. Stattdessen ist das zweite Element tatsächlich eine Anordnung von Elementen selbst.

Warum gibt mein Code nicht nur TableColumn Elemente als direkte Kinder zu meinem Table?

UPDATE Es scheint, dass die folgenden Werke zu tun:

getDefaultSortColumn() { 
    let col = this.props.children[0].props.field; 
    this.props.children.forEach((child: React.ReactElement<any>) => { 
     if (Array.isArray(child)) { 
     child.forEach((column: React.ReactElement<O3TableColumnProps>) => { 
      if (column.props.sortDefault) { 
      col = column.props.field; 
      } 
     }); 
     } 
     else if (child.props.sortDefault) { 
     col = child.props.field; 
     } 
    }); 
    return col as string; 
    } 

Aber ich will meine Kinder nicht wie diese haben zuzugreifen, ob das Element Prüfung ist ein TableColumnProps Elementtyp Ich möchte oder eine Anordnung von TableColumnProps Elementen. Das Problem bleibt bestehen.

Antwort

1

Ihre JSX kompiliert, um etwas nach unten, die wie folgt aussieht:

const TableColumn = React.createElement('div', { field: 'code' }, 'Code') 
const Table = React.createElement('div', {}, [ 
    TableColumn, 
    columns.map((column, i) => 
    React.createElement('div', { key: column, field: column }, column), 
), 
]) 

Sie können die Kinder Table sehen gehören ein Element reagieren, und eine Reihe von Elementen reagieren. Das Iterieren über das Children-Array wird Ihnen genau das geben.

React bietet eine Top-Level-API für diese Art von Sache - React.Children - die untergeordnete Arrays in Ihren Iterationen mit React.Children.map und React.Children.forEach durchquert.

Die eingestellte Funktion würde wie folgt aussehen:

getDefaultSortColumn() { 
    let col = this.props.children[0].props.field; 
    React.Children.forEach(this.props.children, (column) => { 
    if (column.props.sortDefault) { 
     col = column.props.field; 
    } 
    }); 
    return col; 
} 
+0

die in den folgenden Fehler führt: 'Argument vom Typ '(Säule: ReactElement ) => void' auf Parameter des Typs nicht belegbar ist‚(Kind: ReactChild, index: number) => any '. Die Parameter 'Spalte' und 'Kind' sind nicht kompatibel. Der Typ 'ReactChild' kann nicht dem Typ 'ReactElement ' zugewiesen werden. Typ 'Zeichenfolge' ist nicht dem Typ 'ReactElement ' zuweisbar '' – im1dermike

+0

Ein Update zum ursprünglichen Beitrag hinzugefügt. – im1dermike

+0

Typ Überprüfung zur Seite, die Antwort ist immer noch gültig und ist die bevorzugte/empfohlene Methode für das Schleifen über Kinder in React, ohne nach verschachtelten Arrays zu überprüfen. Ich werde die Antwort aktualisieren, um das Bit für die Typprüfung auszuschließen und den Teil herauszufinden. Sehen Sie hier zum Beispiel: https://codesandbox.io/s/jvxqvw3813 –

Verwandte Themen