Website-Suche

javascript - Was bedeutet ...rest in React JSX?


Wenn ich mir dieses React Router Dom v4-Beispiel anschaue https://reacttraining.com/react-router/web/example/auth-workflow sehe ich, dass die PrivateRoute-Komponente eine Rest-Prop so destrukturiert

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    fakeAuth.isAuthenticated ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/login',
        state: { from: props.location }
      }}/>
    )
  )}/>
)

Ich möchte sicher sein, dass { component: Component, ...rest } bedeutet:

Aus props erhältst du die Component-Prop und dann werden dir alle anderen Props gegeben, und benenne props in rest um, damit du Namensprobleme mit den Props vermeiden kannst, die an die Route-render-Funktion übergeben werden

Bin ich richtig?

Antwort #1

Entschuldigung, mir ist aufgefallen, dass meine erste Antwort (während sie hoffentlich immer noch nützliche/zusätzliche Kontextinformationen liefert) Ihre Frage nicht beantwortet. Lassen Sie mich es noch einmal versuchen.

Du fragst:

Ich möchte sicher sein, dass { component: Component, ...rest } bedeutet:

Hol dir aus props die Component-Eigenschaft und dann alle anderen dir gegebenen props, und benenne props in rest um, damit du Namenskonflikte mit den an die Route-render-Funktion übergebenen props vermeiden kannst

Ihre Interpretation ist nicht ganz korrekt. Aufgrund Ihrer Gedanken scheint es jedoch, dass Sie sich zumindest dessen bewusst sind, dass das, was hier passiert, einer Art von Objektzerlegung entspricht (siehe zweite Antwort und die dortigen Kommentare für weitere Klärung).

Um eine genaue Erklärung zu geben, lassen Sie uns den Ausdruck { component: Component, ...rest } in zwei separate Operationen aufteilen:

  1. Operation 1: Finde die component-Eigenschaft, die in props definiert ist (Hinweis: Kleinbuchstabe component) und weise sie einem neuen Ort im State zu, den wir Component nennen (Hinweis: Großbuchstabe Component).
  2. Operation 2: Nimm dann alle verbleibenden Eigenschaften, die im props-Objekt definiert sind, und sammle sie in einem Argument namens rest.

Der wichtige Punkt ist, dass Sie props NICHT in rest umbenennen. (Und es hat auch nichts damit zu tun, zu versuchen, „Namensprobleme mit den props zu vermeiden, die an die Route-render-Funktion übergeben werden“.)

rest === props;
// => false

Du ziehst einfach den Rest der Eigenschaften, die in deinem props-Objekt definiert sind, in ein neues Argument namens rest heraus (daher der Name des Arguments). Es ist übrigens erwähnenswert, dass es vor allem eine Konvention ist, es rest zu nennen. Du könntest es nennen, wie du willst.


Beispielverwendung

const myObj = {
  name: 'John Doe',
  age: 35,
  sex: 'M',
  dob: new Date(1990, 1, 1)
};

Für dieses Beispiel kann es hilfreich sein, props einfach als die gleiche Struktur (d.h., Eigenschaften und Werte) wie in myObj gezeigt zu betrachten. Lassen Sie uns nun die folgende Zuweisung schreiben.

const { name: Username, ...rest } = myObj

Die obige Aussage entspricht sowohl der Deklaration als auch der Zuweisung von zwei Variablen (oder, denke ich, Konstanten). Die Aussage kann folgendermaßen gedacht werden:

Nehmen Sie die Eigenschaft name, die auf myObj definiert ist, und weisen Sie ihren Wert einer neuen Variablen zu, die wir Username nennen. Nehmen Sie dann alle anderen Eigenschaften, die auf myObj definiert wurden (z. B., age, sex und dob), und sammeln Sie sie in einem neuen Objekt, das der Variablen zugewiesen wird, die wir rest nennen.

Das Protokollieren von Username und rest in der Konsole würde dies bestätigen. Wir haben Folgendes:

console.log(Username);
// => John Doe
console.log(rest);
// => { age: 35, sex: 'M', dob: Mon Jan 01 1990 00:00:00 GMT-0800 (PST) }

Nebenbemerkung

Warum nicht die Eigenschaften aus den Props destrukturieren, anstatt die Reset-Parameter-Syntax {prop1, prop2,...remainingProps}= obj zu verwenden?

Stellen Sie sich vor, wir erstellen eine Eingabekomponente wie folgt:

const Input ({label, id, type, onChange,value})=>{
return(
<label htmlFor={id}> {label} </label>
<input id={id} type={type} onChange={onChange} value={value}/>
)
}

Zunächst könnte man denken, dass diese Komponente gut ist, aber tatsächlich gibt es viele andere Attribute für die Eingabe, die wir als Benutzer für diese Komponente nicht hinzufügen können. Siehe hier eine Liste aller Eingabeattribute. Wenn wir also die Komponente wie folgt verwenden:

<Input id={myId} value={myValue} onChange={myOnChange} label={myLabel} type={myType} minLength={30} maxLength={100}/>

Um also alle zusätzlichen Props zu berücksichtigen, die wir übergeben, müssen wir sie destrukturieren, um sie an das Input weiterzugeben. Wir verwenden jedoch tatsächlich nur das Label, und andere Props werden an das Input delegiert. Das bedeutet, dass die verbleibenden Props als ...rest definiert werden, um alle zusätzlichen Props, die wir an die Komponente übergeben, zu erfassen und sie der entsprechenden Komponente oder dem Element hinzuzufügen, was unsere Komponente für mehr Anwendungsfälle nutzbar macht.

Sie fragen sich vielleicht auch:

Warum sich die Mühe machen, die component-Eigenschaft herauszuziehen, nur um sie in Component mit einem Großbuchstaben „C“ umzubenennen?

Ja, es scheint ziemlich trivial zu sein. Und obwohl es eine Standardpraxis in React ist, gibt es einen Grund, warum die gesamte Dokumentation von Facebook zu seinem Framework genau so geschrieben ist. Nämlich ist das Großschreiben von benutzerdefinierten Komponenten, die mit JSX gerendert werden, weniger eine Praxis an sich als eine Notwendigkeit. React, oder besser gesagt JSX, ist groß- und kleinschreibungsempfindlich. Benutzerdefinierte Komponenten, die ohne einen großgeschriebenen Anfangsbuchstaben eingefügt werden, werden nicht in den DOM gerendert. So hat React definiert, wie benutzerdefinierte Komponenten identifiziert werden. Hätte das Beispiel die component-Eigenschaft, die von props gezogen wurde, nicht zusätzlich zu Component umbenannt, würde der Ausdruck <component {...props} /> nicht korrekt gerendert werden und ein <component />-Element im DOM rendern, nicht die eigentliche React-Komponente.

Antwort #2

Es ermöglicht Ihnen, all Ihre props in einem einzigen prägnanten Ausdruck zu „verbreiten“. Zum Beispiel nehmen wir an, die props, die von Ihrer PrivateRoute-Komponente empfangen werden, sehen wie folgt aus

// `props` Object:
{
  thing1: 'Something',
  thing2: 'Something else'
}

Wenn Sie diese Elemente (d.h., thing1 und thing2) weiter an das verschachtelte <Component />-Tag übergeben wollten und mit der Object-Spread-Syntax nicht vertraut waren, könnten Sie schreiben:

<Component
  thing1={ props.thing1 }
  thing2={ props.thing2 } />

Die { ...props }-Syntax macht jedoch eine solche Ausführlichkeit überflüssig, indem sie es Ihnen erlaubt, Ihr props-Objekt auf die gleiche Weise zu verteilen, wie man ein Array von Werten ausbreiten könnte (z. B., [...vals]). Mit anderen Worten, der untenstehende JSX-Ausdruck und der obenstehende sind genau gleichwertig.

<Component { ...props } />

Verwandte Artikel