Heim >Web-Frontend >js-Tutorial >Mehrere erweiterte Methoden zum Zerlegen von React-Komponenten
React-Komponenten sind magisch und äußerst flexibel. Beim Design von Bauteilen können wir mit vielen Tricks spielen. Es ist jedoch sehr wichtig, das Prinzip der Einzelverantwortung der Komponente sicherzustellen: Dadurch können unsere Komponenten einfacher und bequemer gewartet werden, und was noch wichtiger ist, die Komponenten können dadurch wiederverwendbar gemacht werden. In diesem Artikel werden hauptsächlich einige fortgeschrittene Methoden zum Zerlegen von React-Komponenten vorgestellt, in der Hoffnung, Ihnen dabei zu helfen.
Die Zerlegung einer komplexen und aufgeblähten React-Komponente ist jedoch möglicherweise keine einfache Angelegenheit. In diesem Artikel werden drei Methoden zum Zerlegen von React-Komponenten von flacher nach tiefer vorgestellt.
Dies ist die einfachste Methode, die man sich vorstellen kann: Wenn eine Komponente viele Elemente rendert, müssen Sie versuchen, die Rendering-Logik dieser Elemente zu trennen. Der schnellste Weg besteht darin, die render()-Methode in mehrere Sub-Render-Methoden aufzuteilen.
Es wird intuitiver, wenn Sie sich das folgende Beispiel ansehen:
class Panel extends React.Component { renderHeading() { // ... } renderBody() { // ... } render() { return ( <div> {this.renderHeading()} {this.renderBody()} </div> ); } }
Aufmerksame Leser werden schnell feststellen, dass dadurch die Komponente selbst nicht wirklich zerlegt wird. Die Panel-Komponente behält weiterhin ihr Original Zustand. Requisiten und Klassenmethoden.
Wie lässt sich die Komponentenkomplexität wirklich reduzieren? Wir müssen einige Unterkomponenten erstellen. Zu diesem Zeitpunkt ist es auf jeden Fall ein guter Versuch, funktionale Komponenten/zustandslose Komponenten zu übernehmen, die von der neuesten Version von React unterstützt und empfohlen werden:
const PanelHeader = (props) => ( // ...);const PanelBody = (props) => ( // ...);class Panel extends React.Component { render() { return ( <div> // Nice and explicit about which props are used <PanelHeader title={this.props.title}/> <PanelBody content={this.props.content}/> </div> ); } }
Im Vergleich zur vorherigen Methode ist diese subtile Verbesserung revolutionär.
Wir haben zwei neue Unit-Komponenten erstellt: PanelHeader und PanelBody. Dies erleichtert das Testen und wir können verschiedene Komponenten direkt separat testen. Gleichzeitig wird optimistisch erwartet, dass mit Hilfe der neuen Algorithmus-Engine React Fiber von React die Rendering-Effizienz der beiden Unit-Komponenten deutlich verbessert wird.
Zurück zum Ausgangspunkt des Problems: Warum wird eine Komponente aufgebläht und kompliziert? Zum einen gibt es viele verschachtelte Rendering-Elemente, zum anderen gibt es viele Änderungen innerhalb der Komponente oder mehrere Konfigurationen.
An diesem Punkt können wir die Komponente in eine Vorlage umwandeln: Die übergeordnete Komponente ähnelt einer Vorlage und konzentriert sich nur auf verschiedene Konfigurationen.
Lassen Sie mich ein Beispiel geben, damit es klarer zu verstehen ist.
Zum Beispiel haben wir eine Kommentarkomponente, die mehrere Verhaltensweisen oder Ereignisse aufweist.
Gleichzeitig ändern sich die von der Komponente angezeigten Informationen entsprechend der Identität des Benutzers:
Ob der Benutzer der Autor dieses Kommentars ist;
Ob dieser Kommentar korrekt gespeichert wird;
Verschiedene Berechtigungen sind unterschiedlich
Warten...
führt zu einem unterschiedlichen Anzeigeverhalten dieser Komponente.
Anstatt die gesamte Logik durcheinander zu bringen, besteht derzeit vielleicht ein besserer Ansatz darin, React zu verwenden, um die Eigenschaften des React-Elements zwischen Komponenten zu übertragen, sodass es eher einer leistungsstarken Vorlage ähnelt :
class CommentTemplate extends React.Component { static propTypes = { // Declare slots as type node metadata: PropTypes.node, actions: PropTypes.node, }; render() { return ( <div> <CommentHeading> <Avatar user={...}/> // Slot for metadata <span>{this.props.metadata}</span> </CommentHeading> <CommentBody/> <CommentFooter> <Timestamp time={...}/> // Slot for actions <span>{this.props.actions}</span> </CommentFooter> </div> ... ) } }
An dieser Stelle ist unsere eigentliche Kommentarkomponente wie folgt organisiert:
class Comment extends React.Component { render() { const metadata = this.props.publishTime ? <PublishTime time={this.props.publishTime} /> : <span>Saving...</span>; const actions = []; if (this.props.isSignedIn) { actions.push(<LikeAction />); actions.push(<ReplyAction />); } if (this.props.isAuthor) { actions.push(<DeleteAction />); } return <CommentTemplate metadata={metadata} actions={actions} />; } }
Metadaten und Aktionen sind tatsächlich die React-Elemente, die unter bestimmten Umständen gerendert werden müssen.
Zum Beispiel:
Wenn this.props.publishTime vorhanden ist, lauten die Metadaten
Das Gegenteil ist Sparen....
Wenn sich der Benutzer angemeldet hat, muss es gerendert werden (d. h. der Aktionswert ist)
class Document extends React.Component { componentDidMount() { ReactDOM.findDOMNode(this).addEventListener('click', this.onClick); } componentWillUnmount() { ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick); } onClick = (e) => { // Naive check for <a> elements if (e.target.tagName === 'A') { sendAnalytics('link clicked', { // Specific information to be sent documentId: this.props.documentId }); } }; render() { // ... } }Einige Probleme dabei sind:
function withLinkAnalytics(mapPropsToData, WrappedComponent) { class LinkAnalyticsWrapper extends React.Component { componentDidMount() { ReactDOM.findDOMNode(this).addEventListener('click', this.onClick); } componentWillUnmount() { ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick); } onClick = (e) => { // Naive check for <a> elements if (e.target.tagName === 'A') { const data = mapPropsToData ? mapPropsToData(this.props) : {}; sendAnalytics('link clicked', data); } }; render() { // Simply render the WrappedComponent with all props return <WrappedComponent {...this.props} />; } } ... }Es ist zu beachten, dass die Funktion „withLinkAnalytics“ die WrappedComponent-Komponente selbst nicht ändert Ändern Sie das Verhalten der WrappedComponent-Komponente. Stattdessen wird eine neue verpackte Komponente zurückgegeben. Die tatsächliche Verwendung ist:
class Document extends React.Component { render() { // ... } } export default withLinkAnalytics((props) => ({ documentId: props.documentId }), Document);Auf diese Weise muss sich die Dokumentkomponente weiterhin nur um die Teile kümmern, um die sie sich kümmern sollte, und mitLinkAnalytics besteht die Möglichkeit, statistische Logik wiederzuverwenden.
Die Existenz von Komponenten höherer Ordnung zeigt perfekt die angeborenen Kompositionsfähigkeiten von React. In der React-Community haben React-Redux, Styled-Components, React-Intl usw. diese Methode im Allgemeinen übernommen. Es ist erwähnenswert, dass die Recompose-Klassenbibliothek Komponenten höherer Ordnung nutzt und diese weiterführt, um „gehirnerweiternde“ Dinge zu erreichen.
Der Aufstieg von React und den umliegenden Communities hat funktionale Programmierung immer beliebter gemacht. Ich denke, die Ideen zum Zerlegen und Komponieren sind es wert, gelernt zu werden. Gleichzeitig ist ein Vorschlag für Entwicklung und Design, dass Sie unter normalen Umständen nicht zögern sollten, Ihre Komponenten in kleinere und einfachere Komponenten aufzuteilen, da dies zu Robustheit und Wiederverwendung führen kann.
Verwandte Empfehlungen:
Beispielanalyse für den Lebenszyklus von React-Komponenten
Die umfassendste Methode zum Erstellen von React-Komponenten
Detaillierte Erklärung, wie der Store React-Komponenten optimiert
Das obige ist der detaillierte Inhalt vonMehrere erweiterte Methoden zum Zerlegen von React-Komponenten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!