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
propserhältst du die Component-Prop und dann werden dir alle anderen Props gegeben, und benennepropsinrestum, 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
propsdieComponent-Eigenschaft und dann alle anderen dir gegebenenprops, und benennepropsinrestum, damit du Namenskonflikte mit den an die Route-render-Funktion übergebenenpropsvermeiden 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:
- Operation 1: Finde die
component-Eigenschaft, die inpropsdefiniert ist (Hinweis: Kleinbuchstabe component) und weise sie einem neuen Ort im State zu, den wirComponentnennen (Hinweis: Großbuchstabe Component). - Operation 2: Nimm dann alle verbleibenden Eigenschaften, die im
props-Objekt definiert sind, und sammle sie in einem Argument namensrest.
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 aufmyObjdefiniert ist, und weisen Sie ihren Wert einer neuen Variablen zu, die wirUsernamenennen. Nehmen Sie dann alle anderen Eigenschaften, die aufmyObjdefiniert wurden (z. B.,age,sexunddob), und sammeln Sie sie in einem neuen Objekt, das der Variablen zugewiesen wird, die wirrestnennen.
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}= objzu 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 inComponentmit 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 } />
