Wie vermeidet man die Bindung innerhalb der Rendermethode?

Wir sollten die Methodenbindung in render vermeiden, da beim erneuten Rendern die neuen Methoden erstellt werden, anstatt die alte zu verwenden, was sich auf die Performance auswirkt.

Also für die Szenarien wie folgt:

 

Wir können die _handleChange Methode entweder im Konstruktor binden:

 this._handleChange = this._handleChange.bind(this); 

Oder wir können die Property Initializersyntax verwenden :

 _handleChange = () => {....} 

Nun betrachten wir den Fall, wo wir einige zusätzliche Parameter übergeben wollen, sagen wir in einer einfachen Todo-App, beim Anklicken des Elements muss ich das Element aus dem Array löschen, dafür muss ich entweder den Objekt-Index oder den Todo-Namen in jedem übergeben onClick-Methode:

 todos.map(el => 
{el}
)

Nehmen wir einmal an, dass Todo-Namen eindeutig sind.

Wie DOC :

Das Problem mit dieser Syntax besteht darin, dass bei jeder Wiedergabe der Komponente ein anderer callback erstellt wird.

Frage:

Wie vermeidet man diese Art der Bindung innerhalb der Rendermethode oder welche Alternativen gibt es?

Bitte geben Sie eine Referenz oder ein Beispiel, danke.

Erstens: Eine einfache Lösung besteht darin, eine Komponente für den Inhalt innerhalb einer Map-function zu erstellen und die Werte als Requisiten zu übergeben. Wenn Sie die function von der Child-Komponente aufrufen, können Sie den Wert an die als Props übergebene function übergeben.

Elternteil

 deleteTodo = (val) => { console.log(val) } todos.map(el =>  ) 

Meine Komponente

 class MyComponent extends React.Component { deleteTodo = () => { this.props.onClick(this.props.val); } render() { return 
{this.props.val}
} }

Beispielschnipsel

 class Parent extends React.Component { _deleteTodo = (val) => { console.log(val) } render() { var todos = ['a', 'b', 'c']; return ( 
{todos.map(el => )}
) } } class MyComponent extends React.Component { _deleteTodo = () => { console.log('here'); this.props.onClick(this.props.val); } render() { return
{this.props.val}
} } ReactDOM.render(, document.getElementById('app'));
   

Diese Antwort https://stackoverflow.com/a/45053753/2808062 ist definitiv erschöpfend, aber ich würde sagen, dass es besser ist, dieses Problem zu lösen, indem Sie ein richtiges shouldComponentUpdate in der shouldComponentUpdate implementieren.

Auch wenn die Requisiten genau gleich sind, shouldComponentUpdate der folgende Code die shouldComponentUpdate immer noch, es sei denn, sie verhindern dies in ihrer eigenen shouldComponentUpdate (sie könnten sie von PureComponent erben):

 handleChildClick = itemId => {} render() { return this.props.array.map(itemData =>  

Beweis: https://jsfiddle.net/69z2wepo/92281/ .

Um erneute shouldComponentUpdate zu vermeiden, muss die shouldComponentUpdate Komponente shouldComponentUpdate trotzdem shouldComponentUpdate implementieren. Die einzige sinnvolle Implementierung ist es, onClick ignorieren, unabhängig davon, ob es sich geändert hat:

 shouldComponentUpdate(nextProps) { return this.props.array !== nextProps.array; } 

Wie vermeidet man diese Art der Bindung innerhalb der Rendermethode oder welche Alternativen gibt es?

Wenn Sie sich für ein Re-Rendering shouldComponentUpdate dann sollten shouldComponentUpdate und PureComponent Ihre Freunde sein und sie werden Ihnen helfen, das Rendering zu optimieren.

Sie müssen die “Child” -Komponente aus dem “Parent” extrahieren und immer die gleichen Requisiten übergeben und ” shouldComponentUpdate implementieren shouldComponentUpdate oder ” PureComponent . Was wir wollen, ist ein Fall, wenn wir ein Kind entfernen, andere Kinder sollten nicht erneut gerendert werden.

Beispiel

 import React, { Component, PureComponent } from 'react'; import { render } from 'react-dom'; class Product extends PureComponent { render() { const { id, name, onDelete } = this.props; console.log(` render()`); return ( 
  • {id} - {name}
  • ); } } class App extends Component { constructor(props) { super(props); this.state = { products: [ { id: 1, name: 'Foo' }, { id: 2, name: 'Bar' }, ], }; this.handleDelete = this.handleDelete.bind(this); } handleDelete(productId) { this.setState(prevState => ({ products: prevState.products.filter(product => product.id !== productId), })); } render() { console.log(` render()`); return (

    Products

      { this.state.products.map(product => ( )) }
    ); } } render(, document.getElementById('root'));

    Demo: https://codesandbox.io/s/99nZGlyZ

    Erwartetes Verhalten

    • render()

    Wenn wir entfernen, wird nur neu gerendert.

    • machen()

    Um diese Nachrichten in der Demo zu sehen, öffne die Dev-Tools-Konsole.

    Die gleiche Technik wird verwendet und im Artikel beschrieben: Reagieren ist langsam, Reagieren ist schnell: React Apps in der Praxis von François Zaninotto zu optimieren.

    Sie können die curried-function verwenden, um Werte zu kapseln

     class MyComponent extends React.Component { constructor() { this.deleteTodo = this.deleteTodo.bind(this); } deleteTodo = (el) => () => { this.props.onClick(el, this.props.val); } render() { return 
    {el}
    } }

    mehr Details hier: https://www.sitepoint.com/currying-in-functional-javascript/