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
neu gerendert.
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/