Nehmen wir an, ich habe eine Ansichtskomponente mit einem bedingten Rendering:
render(){
if (this.state.employed) {
return (
<div>
<MyInput ref="job-title" name="job-title" />
</div>
);
} else {
return (
<div>
<MyInput ref="unemployment-reason" name="unemployment-reason" />
<MyInput ref="unemployment-duration" name="unemployment-duration" />
</div>
);
}
}
MyInput sieht ungefähr so aus:
class MyInput extends React.Component {
...
render(){
return (
<div>
<input name={this.props.name}
ref="input"
type="text"
value={this.props.value || null}
onBlur={this.handleBlur.bind(this)}
onChange={this.handleTyping.bind(this)} />
</div>
);
}
}
Sagen wir, employed
ist wahr. Immer wenn ich es auf false umschalte und die andere Ansicht gerendert wird, wird nur unemployment-duration
neu initialisiert. Auch unemployment-reason
wird mit dem Wert aus vorbelegt job-title
(wenn ein Wert gegeben wurde , bevor der Zustand geändert).
Wenn ich das Markup in der zweiten Renderroutine in etwa so ändere:
render(){
if (this.state.employed) {
return (
<div>
<MyInput ref="job-title" name="job-title" />
</div>
);
} else {
return (
<div>
<span>Diff me!</span>
<MyInput ref="unemployment-reason" name="unemployment-reason" />
<MyInput ref="unemployment-duration" name="unemployment-duration" />
</div>
);
}
}
Es scheint, als ob alles gut funktioniert. Es sieht so aus, als würde React die Berufsbezeichnung und den Grund für die Arbeitslosigkeit nicht unterscheiden.
Bitte sag mir, was ich falsch mache ...
javascript
reactjs
o01
quelle
quelle
data-reactid
auf jedem derMyInput
(oderinput
, wie in DOM zu sehen) Elemente vor und nach dememployed
Wechsel?<div>
. Diedata-reactid
Attribute scheinen sowohl im Wrapping-Div als auch im Eingabefeld unterschiedlich zu sein.job-title
Eingabe erhält IDdata-reactid=".0.1.1.0.1.0.1"
, währendunemployment-reason
Eingabe ID erhältdata-reactid=".0.1.1.0.1.2.1"
unemployment-duration
?reactid
Attribute identischjob-title
undunemployment-reason
im zweiten Beispiel (mit der diff span) unterschiedlich.unemployment-duration
dasreactid
Attribut ist immer eindeutig.Antworten:
Was wahrscheinlich passiert, ist, dass React denkt, dass nur eins
MyInput
(unemployment-duration
) zwischen den Renderings hinzugefügt wird. Als solches wird dasjob-title
nie durch das ersetztunemployment-reason
, weshalb auch die vordefinierten Werte vertauscht werden.Wenn React den Diff ausführt, wird anhand ihrer
key
Eigenschaft bestimmt, welche Komponenten neu und welche alt sind . Wenn der Code keinen solchen Schlüssel enthält, generiert er einen eigenen.Der Grund, warum das letzte von Ihnen bereitgestellte Code-Snippet funktioniert, ist, dass React im Wesentlichen die Hierarchie aller Elemente unter dem übergeordneten Element ändern muss,
div
und ich glaube, dass dies ein erneutes Rendern aller untergeordneten Elemente auslösen würde (weshalb es funktioniert). Hätten Siespan
das unten statt oben hinzugefügt , würde sich die Hierarchie der vorhergehenden Elemente nicht ändern und diese Elemente würden nicht neu gerendert (und das Problem würde bestehen bleiben).In der offiziellen React-Dokumentation heißt es:
Sie sollten dies beheben können, indem
key
Sie dem übergeordneten Elementdiv
oder allenMyInput
Elementen selbst ein eindeutiges Element bereitstellen .Beispielsweise:
ODER
Wenn React nun den Diff ausführt, wird es feststellen, dass die
divs
Unterschiede unterschiedlich sind, und es wird einschließlich aller seiner untergeordneten Elemente neu gerendert (1. Beispiel). Im zweiten Beispiel wird der Diff ein Erfolg seinjob-title
undunemployment-reason
da sie jetzt unterschiedliche Schlüssel haben.Sie können natürlich alle gewünschten Schlüssel verwenden, sofern diese eindeutig sind.
Update August 2017
Um einen besseren Einblick in die Funktionsweise von Schlüsseln in React zu erhalten, empfehle ich dringend, meine Antwort auf Grundlegendes zu eindeutigen Schlüsseln in React.js zu lesen .
Update November 2017
Dieses Update sollte vor einiger Zeit veröffentlicht worden sein, aber die Verwendung von String-Literalen in
ref
ist jetzt veraltet. Zum Beispielref="job-title"
sollte jetzt stattdessen seinref={(el) => this.jobTitleRef = el}
(zum Beispiel). Weitere Informationen finden Sie in meiner Antwort auf die Warnung vor Verfall mit this.refs .quelle
it will determine which components are new and which are old based on their key property.
- das war ... Schlüssel ... zu meinem VerständnisÄndern Sie den Schlüssel der Komponente.
Die Komponente wird nicht gemountet und eine neue Instanz der Komponente wird gemountet, da sich der Schlüssel geändert hat.
Bearbeiten : Dokumentiert über Sie benötigen wahrscheinlich keinen abgeleiteten Status :
quelle
Verwenden Sie
setState
in Ihrer Ansicht, um dieemployed
Eigenschaft des Status zu ändern . Dies ist ein Beispiel für die React-Render-Engine.quelle
Ich arbeite an Crud für meine App. So habe ich es gemacht Got Reactstrap als meine Abhängigkeit.
Einige React Hooks drin
quelle