Reagieren Die Code-Style-Guide

0
34

Ich habe mit der Zeit meines Lebens mit Reagieren in letzter Zeit. Aber auf meiner Reise, ich habe eine harte Zeit der Suche nach guten code-Stil-Richtlinien zu halten, die Mischung von JSX und JS sauber und lesbar. Ich habe kommen mit meinen eigenen style guides, die ich lieben würde, zu teilen. Diese vielleicht für Sie nützlich sein, und, natürlich, fühlen Sie sich frei zu teilen, ähnliche Richtlinien in den Kommentar-thread unterhalb.

Regel #1: Destructure Ihre Requisiten

Einer meiner Lieblings-ES6-features ist destructuring. Es macht die Zuordnung Objekt-Eigenschaften, um die Variablen zu fühlen, wie viel weniger eine lästige Pflicht. Werfen wir einen Blick auf ein Beispiel.

Sagen wir, wir haben einen Hund, den wir anzeigen möchten, wie ein div mit einer Klasse benannt nach seiner Rasse. Innerhalb des div ist ein Satz, der Noten der Hund die Farbe und sagt uns, ob es ein guter Hund oder böser Hund.

class Hund extends Component {
render () {
Rückkehr <div className={das.Requisiten.Rasse}>Mein {dies.Requisiten.color} Hund {dies.Requisiten.isGoodBoy ? “gut” : “bad”}</div>;
}
}

Das technisch macht, was wir wollen, aber es scheint wie ein ziemlich großer block von code für das, was wirklich ist, nur drei Variablen und eine HTML-tag.

Wir können es brechen sich durch die Zuordnung aller der Eigenschaften von Requisiten, um lokale Variablen.

lassen Sie züchten =.Requisiten.Rasse;
lassen Sie color = diese.Requisiten.Farbe;
lassen Sie isGoodBoy =.Requisiten.isGoodBoy;

Mit ES6, wir setzen es in eine saubere Aussage wie diese:

lassen Sie { Rasse, Farbe, isGoodBoy } =.Requisiten;

Zu halten alles sauber, wir setzen unsere ternärer operator (dazu später mehr) in eine eigene variable, und viola.

class Hund extends Component {
render () {
lassen Sie { Rasse, Farbe, isGoodBoy } =.Requisiten;
lassen Bezeichner = isGoodBoy ? “gut” : “bad”;
Rückkehr <div className={Rasse}>Mein {color} Hund {identifier}</div>;
}
}

Viel einfacher zu Lesen.

Regel #2: Ein tag, eine Zeile

Nun, wir hatten alle diesen moment, wo wir wollen, um unsere gesamte Funktion und machen es zu einem Brei von Betreibern und kleine parameter-Namen, um einige uglified, superfast, unlesbar utility-Funktion. Allerdings, wenn Sie eine zustandslose Komponente Reagieren, können Sie ziemlich leicht tun die gleiche Sache, während die übrigen reinigen.

class Hund extends Component {
render () {
lassen Sie { Rasse, Farbe, goodOrBad } =.Requisiten;
Rückkehr <div className={Rasse}>Mein {color} Hund {goodOrBad}</div>;
}
}

vs.

lassen Sie Hund = (Rasse, Farbe, goodOrBad) => <div className={Rasse}>Mein {color} Hund {goodOrBad}</div>;

Wenn alles, was Sie tun, ist machen ein basic-element und Platzierung der Eigenschaften in ein HTML-tag, dann Mach dir keine sorgen machen so eine große Sache, alle Funktionen und Wrapper um eine komplett andere Klasse gehen. Eine Zeile code zu tun.

Sie können selbst kreativ werden mit einigen ES6-spread-Funktionen wenn Sie ein Objekt übergeben, für Ihre Eigenschaften. Die Nutzung dieser.Requisiten.Inhalt wird automatisch die Zeichenfolge zwischen den öffnen und schließen-tag.

lassen Sie propertiesList = {
className: “meine-Lieblings-Komponente”,
id: “myFav”,
Inhalt: “Hello world!”
};
lassen Sie SimpleDiv = props => <div {… props} />;

lassen Sie jsxVersion = <SimpleDiv props={propertiesList} />;

Verwenden der spread-Funktion:

  • Keine ternären Operatoren erforderlich
  • Nur die Weitergabe der HTML-tag-Attribute und Inhalte
  • Kann mehrfach verwendet werden

Wenn nicht , verwenden die spread-Funktion:

  • Dynamische Eigenschaften
  • Array oder Objekt-Eigenschaften gefordert sind
  • Ein render, der erforderlich wäre, verschachtelte tags

Regel #3: Die Regel der 3

Wenn Sie drei oder mehr Eigenschaften, dann legen Sie Sie auf Ihre eigene Linie sowohl in der Instanz und in der render-Funktion.

Dies würde in Ordnung sein, um nur eine Zeile von Eigenschaften:

Klasse GalleryImage extends Component {
render () {
lassen Sie { imgSrc, Titel } =.Requisiten;
return (
<Abbildung>
<img src= ” {imgSrc} alt={Titel} />
<figcaption>
<p>Title: {title}</p>
</figcaption>
</figure>
);
}
}

Aber Bedenken Sie:

Klasse GalleryImage extends Component {
render () {
lassen Sie { imgSrc, Titel, Künstler, clas, thumbnail, Haltepunkt } =.Requisiten;
return (
<Abbildung className={kl}>
<Bild>
<source media={`(min-width: ${Haltepunkt})`} srcset={imgSrc} />
<img src= ” {thumbnail} alt={Titel} />
</Bild>
<figcaption>
<p>Title: {title}</p>
<p>Artist: {artist}</p>
</figcaption>
</figure>
);
}
}

Oder die render:

<GalleryImage imgSrc=”./src/img/vangogh2.jpg” title=”Starry Night” artist=”Van Gogh” clas=”portrait” thumbnail=”./src/img/thumb/vangogh2.gif” Haltepunkt={320} />

Es kann sein, zu viel von einem codeblock zu Lesen. Drop jede Eigenschaft der nächsten Zeile für eine saubere, gut lesbare Aussehen:

lassen Sie { imgSrc,
Titel,
Künstler,
clas,
thumbnail
Haltepunkt } =.Requisiten;

und:

<GalleryImage
imgSrc=”./src/img/vangogh2.jpg”
title=”Starry Night”
Künstler=”Van Gogh”
clas=”Landschaft”
thumbnail=”./src/img/thumb/vangogh2.gif”
Haltepunkt={320} />

Regel #4: Zu viele Eigenschaften?

Property management ist schwierig, auf jeder Ebene, aber mit ES6 destructuring Reagieren und state-basierten Ansatz, es gibt durchaus ein paar Möglichkeiten, um aufzuräumen das Aussehen eine Menge von Eigenschaften.

Sagen wir, wir machen ein mapping-Anwendung, die eine Liste von gespeicherten Adressen und GPS-Koordinaten-für Ihren aktuellen Standort.

Die aktuelle Benutzer-Informationen der position und der Nähe zu den Lieblings-Adresse sollte in der parent-Komponente der App wie diese:

Klasse App extends Component {
Konstruktor (props) {
super(props);
diese.state = {
userLat: 0,
userLon: 0,
isNearFavoriteAddress: false
};
}
}

Also, wenn wir eine Adresse und wollen wir es beachten, wie nahe man an die Adresse, die wir übergeben haben mindestens zwei Eigenschaften von der App.

In-App-render ():

<Adresse
… // Informationen über die Adresse
currentLat={das.Zustand.userLat}
currentLong={das.Zustand.userLon} />

In der render-Funktion für die Adresse der Komponente:

render () {
lassen Sie { Hausnummer,
streetName,
streetDirection,
Stadt,
Zustand,
zip,
lat,
lon,
currentLat,
currentLon } =.Requisiten;
return ( … );
}

Schon können Sie sehen, wie das wird langsam unhandlich. Nehmen wir die beiden Sätze von Informationen, und brechen Sie in Ihre eigenen Objekte, es wird viel mehr überschaubar.

In unserer App-Konstruktor ():

diese.state = {
userPos: {
lat: 0,
lon: 0
},
isNearFavoriteAddress: false
};

An einem gewissen Punkt vor der App von render ():

lassen Sie addressList = [];
addressList.push({
Hausnummer: “1234”,
streetName: “Street Rd”,
streetDirection: “N”,
Stadt: “Stadt”,
Zustand: “ST”,
zip: “12345”,
lat: “019782309834”,
lon: “023845075757”
});

In-App-render ():

<Adresse addressInfo={addressList[0]} userPos={das.Zustand.userPos} />

In der render-Funktion für die Adresse-Komponente

render () {
lassen Sie { addressInfo, userPos } =.Requisiten;
lassen Sie { Hausnummer,
streetName,
streetDirection,
Stadt,
Zustand,
zip,
lat,
lon } = addressInfo;
return ( … );
}

Viel, viel sauberer. Reagiert hat auch einige große Möglichkeiten, um sicherzustellen, dass die Eigenschaften im Objekt vorhanden sind und von einem bestimmten Typ mit PropTypes, dass wir normalerweise nicht in JavaScript, das ist nur ein guter OOP-Sache sowieso.

Regel #5: Dynamische macht – Mapping-arrays aus

Ziemlich Häufig in HTML -, schreiben wir die gleiche grundlegende Teile des Codes über und über, nur mit ein paar wichtige Unterschiede. Dies ist der Grund, warum Reagieren wurde in Erster Linie erstellt. Sie machen ein Objekt mit Eigenschaften, die eine komplexe, dynamische HTML-block, ohne zu schreiben, jeder Teil von Ihr wiederholt.

JavaScript ist schon ein toller Weg, um Listen zu tun, wie Informationen: arrays!

Reagieren verwendet .map () – Funktion zu legen, die arrays in Ordnung, mit einem parameter aus den arrays als Schlüssel.

render () {
lassen Sie pokemon = [ “Pikachu”, “Schiggy”, “Bulbasaur”, “Glurak” ];
return (
<ul>
{pokemon.anzeigen (- name => <li key={name}>{name}</li>)}
</ul>
);
}

Sie können sogar unsere handy-dandy-spread-Funktionen werfen eine ganze Liste von Parametern, die von einem Objekt mit dem Objekt.- Tasten() (wenn man bedenkt, dass müssen wir noch einen Schlüssel).

render () {
lassen Sie pokemon = {
“Pikachu”: {
Typ: “Electric”,
Stufe: 10
},
“Schiggy”: {
Typ: “Wasser”,
Stufe: 10
},
“Bulbasaur”: {
Typ: “Gras”,
Stufe: 10
},
“Glurak”: {
Typ: “Feuer”,
Stufe: 10
}
};
return (
<ul>
{Object.Schlüssel(pokemon).anzeigen (- name => <Pokemon key={name} {… pokemon[name]} />)}
</ul>
);
}

Regel #6: Dynamische macht – Reagieren ternäre Operatoren

In Reagieren, können Sie mit Operatoren zu tun, ein bedingtes Rendern wie eine Variablen Deklaration. In Regel #1, schauten wir uns das für die Angabe, ob unser Hund gut oder schlecht war. Es ist nicht völlig notwendig, um eine ganze Zeile code zu entscheiden, ein ein-Wort-Unterschied in einem Satz, aber wenn es um große code-Blöcke, es ist schwer zu finden wenig ?’s, und :’s ist.

Klasse SearchResult extends Component {
render () {
lassen Sie { Ergebnisse } =.Requisiten;
return (
<section className=”search-results”>
{die Ergebnisse.length > 0 &&
Ergebnisse.map(index => <Result key={index} {… Ergebnisse[index]”/>)
}
{die Ergebnisse.length === 0 &&
<div className=”no-results”>Keine Ergebnisse</div>
}
</section>
);
}
}

Oder, im wahren ternären Mode

Klasse SearchResult extends Component {
render () {
lassen Sie { Ergebnisse } =.Requisiten;
return (
<section className=”search-results”>
{die Ergebnisse.Länge > 0
? Ergebnisse.map(index => <Result key={index} {… Ergebnisse[index]”/>)
: <div className=”no-results”>Keine Ergebnisse</div>
}
</section>
);
}
}

Auch mit unserer ordentlichen Ergebnis-mapping, können Sie sehen, wie die Halterungen sind bereits Verschachtelung ganz dicht. Nun, stellen Sie sich vor, wenn unsere render hatte mehr als nur eine Zeile. Es kann ziemlich schnell unlesbar. Überlegen Sie sich eine alternative:

Klasse SearchResult extends Component {
render () {
lassen Sie { Ergebnisse } =.Requisiten;
lassen Sie outputJSX;
wenn (results.length > 0) {
outputJSX = (
<Fragment>
{die Ergebnisse.map(index => <Result key={index} {… Ergebnisse[index]”/>)}
</Fragment>
);
} else {
outputJSX = <div className=”no-results”>Keine Ergebnisse</div>;
}
zurück <section className=”search-results”>{Ausgabe}</section>;
}
}

Letztlich ist die code-Länge ist ungefähr das gleiche, aber es gibt einen wichtigen Unterschied: mit dem ersten Beispiel, sind wir schnell hin-und herschalten zwischen zwei verschiedenen Schreibweisen, so dass die visuelle Analyse der Besteuerung und schwierig, während der zweite ist einfach plain JavaScript mit Wert Zuweisungen in einer, einheitliche Sprache und eine Online-Funktion zurück in eine andere.

Die Faustregel in dieser situation ist, dass, wenn die JavaScript, die Sie setzen in Ihre JSX-Objekt ist mehr als zwei Wörter (z.B. Objekt.Eigentum), es sollte getan werden , bevor der Rückruf.

Wrap-up

Die Kombination von syntax können sich chaotisch, und diese sind die offensichtlichsten Situationen, wo ich sah, wie mein code gehen aus den Schienen. Hier sind die grundlegenden Konzepte, die diese stammen alle aus und können auf jede situation, die nicht hier behandelt werden:

  • Verwenden ES6-features. Ernst. Es gibt eine Menge von fantastischen features, die Ihre Arbeit leichter, schneller und weniger manuelle.
  • Nur schreiben JSX auf der rechten Seite von ” = ” oder eine Rückkehr.
  • Manchmal müssen Sie JavaScript in Ihrem JSX. Wenn Sie in JavaScript nicht auf eine Zeile passen (wie ein .map () – Funktion oder ternärer operator), dann sollte es vorher getan werden.
  • Wenn Ihr code beginnt die Suche wie (<{`${()}`} />), dann hast du wohl zu weit gegangen. Nehmen Sie die Unterste Ebene, die außerhalb der aktuellen Anweisung und vor dieser.