2016-05-04 11 views
1

ich einen Code-Schnipsel haben wie dieseAlle TableRows werden jedes Mal, wenn eine Zeile erneut gerendert mit Reagieren und Material-ui ausgewählt ist

<Table selectable onRowSelection={this.onRecordSelected} bodyStyle={tableBodyStyle}> 
     <TableBody deselectOnClickaway={false} showRowHover displayRowCheckbox={false}> 
      {this.props.taskRecords.map((row, index) => (
      <TableRow key={row.get('id')} selected={this.state.selectedRecordRowId === index}> 
       <TableRowColumn>{row.getIn(['task', 'name'])}</TableRowColumn> 
       <TableRowColumn>{row.getIn(['task', 'description'])}</TableRowColumn> 
       <TableRowColumn>{row.get('status')}</TableRowColumn> 
       <TableRowColumn>{row.get('log')}</TableRowColumn> 
      </TableRow> 
     ))} 
     </TableBody> 
</Table> 

ich den Quellcode von TableRow und TableRowColumn geprüft, fand ich sie nicht umsetzen shouldComponentUpdate Methode. Ich verstehe, dass sie neu gerendert werden würden, wenn sich ein Zustand ändert.

Ich habe versucht, pure Funktion in recompose Bibliothek zu verwenden, um diese zu Komponenten zu reinigen.

Sie noch erneut gerendert wurden enter image description here

In meinem Verständnis Komponenten nach der Reinigung nicht mehr erneut gerendert werden, wenn gegeben props werden nicht verändert. In diesem Fall sind alle Stützen entweder unveränderbare Objekte von oder Funktionen.

Gibt es eine Möglichkeit zu verhindern, dass es neu erstellt, wenn ich eine Zeile auswähle?

Vielen Dank im Voraus.

Antwort

0

Im Allgemeinen ja - render Funktion wird jedes Mal in TableRow und TableRowColumn, wenn ihre Stammkomponente wird erneut gerendert genannt werden, aber es ist nicht so schlimm, denn render Funktion, nicht Ihre RealDOM jedes Mal ändern, so ist es nicht so schlecht für deine Anwendungsleistung. Aber, wenn Sie das wirklich aus Gründen verhindern wollen, können Sie zum Beispiel die neue Komponente MyRow erstellen und sie anstelle von TableRow + TableRowColumn rendern.

So wird Ihr Code wie:

<Table selectable onRowSelection={this.onRecordSelected} bodyStyle={tableBodyStyle}> 
    <TableBody deselectOnClickaway={false} showRowHover displayRowCheckbox={false}> 
     {this.props.taskRecords.map((row, index) => (
     <MyRow key={index} row={row} isSelected={this.state.selectedRecordRowId === index} /> 
    ))} 
    </TableBody> 
</Table> 

Und in MyRow Komponente können Sie shouldComponentUpdate (oder PureRenderMixin) und real render Material-ui-Komponenten implementieren:

render() { 
    var isSelected = this.props.isSelected; 
    var row = this.props.row; 
    return <TableRow key={row.get('id')} selected={isSelected}> 
      <TableRowColumn>{row.getIn(['task', 'name'])}</TableRowColumn> 
      <TableRowColumn>{row.getIn(['task', 'description'])}</TableRowColumn> 
      <TableRowColumn>{row.get('status')}</TableRowColumn> 
      <TableRowColumn>{row.get('log')}</TableRowColumn> 
    </TableRow> 
} 
+0

Vielen Dank für Ihre Lösung! Das Problem mit diesem Ansatz besteht nach dem Umbrechen der 'TableRow' in' MyRow', der onSelect-Handler von 'TableRow' funktioniert nicht richtig. – kaze13

+0

Tut mir leid, aber ich sehe keine 'onSelect'-Handler in 'TableRow' component =/Ich habe die offizielle Dokumentation und https://github.com/callemall/material-ui/blob/master/src/Table überprüft /TableRow.js Quelldatei – steppefox

2

Schließlich fand ich eine Lösung.

<Table selectable onRowSelection={this.onRecordSelected} bodyStyle={tableBodyStyle}> 
     <TableBody deselectOnClickaway={false} showRowHover displayRowCheckbox={false}> 
      {this.props.taskRecords.map((row, index) => (
      <PureRecordRow key={row.get('id')} selected={this.state.selectedRecordRowId === index}> 
       <TableRowColumn>{row.getIn(['task', 'name'])}</TableRowColumn> 
       <TableRowColumn>{row.getIn(['task', 'description'])}</TableRowColumn> 
       <TableRowColumn>{row.get('status')}</TableRowColumn> 
       <TableRowColumn>{row.get('log')}</TableRowColumn> 
      </PureRecordRow> 
     ))} 
     </TableBody> 
</Table> 

Ich habe eine neue Komponente PureRecordRow die die TableRow mit benutzerdefinierten shouldComponentUpdate Methode erweitert:

class PureRecordRow extends TableRow{ 
    constructor(props, context){ 
    super(props, context) 
    } 
    shouldComponentUpdate(nextProps, nextState) { 
    return this.state.hovered !== nextState.hovered || this.props.selected !== nextProps.selected; 
    } 
}