Ich schreibe ein Skript, das die Dropdown-Liste je nach Dropdown-Höhe und Position der Eingabe auf dem Bildschirm unter oder über die Eingabe verschiebt. Außerdem möchte ich den Modifikator entsprechend seiner Richtung auf Dropdown setzen. Wenn Sie jedoch das setState
Innere des verwenden, componentDidUpdate
entsteht eine Endlosschleife (was offensichtlich ist).
Ich habe eine Lösung gefunden, getDOMNode
indem ich den Klassennamen direkt als Dropdown-Liste verwendet und festgelegt habe, aber ich bin der Meinung, dass es mit den React-Tools eine bessere Lösung geben sollte. Kann mir jemand helfen?
Hier ist ein Teil des Arbeitscodes mit getDOMNode
(ua etwas vernachlässigte Positionierungslogik zur Vereinfachung des Codes)
let SearchDropdown = React.createClass({
componentDidUpdate(params) {
let el = this.getDOMNode();
el.classList.remove('dropDown-top');
if(needToMoveOnTop(el)) {
el.top = newTopValue;
el.right = newRightValue;
el.classList.add('dropDown-top');
}
},
render() {
let dataFeed = this.props.dataFeed;
return (
<DropDown >
{dataFeed.map((data, i) => {
return (<DropDownRow key={response.symbol} data={data}/>);
})}
</DropDown>
);
}
});
und hier ist Code mit setstate (der eine Endlosschleife erzeugt)
let SearchDropdown = React.createClass({
getInitialState() {
return {
top: false
};
},
componentDidUpdate(params) {
let el = this.getDOMNode();
if (this.state.top) {
this.setState({top: false});
}
if(needToMoveOnTop(el)) {
el.top = newTopValue;
el.right = newRightValue;
if (!this.state.top) {
this.setState({top: true});
}
}
},
render() {
let dataFeed = this.props.dataFeed;
let class = cx({'dropDown-top' : this.state.top});
return (
<DropDown className={class} >
{dataFeed.map((data, i) => {
return (<DropDownRow key={response.symbol} data={data}/>);
})}
</DropDown>
);
}
});
quelle
setState
wird immer ausgelöst eine erneute machen. Anstatt mehrmals zu prüfenstate.top
und aufzurufensetState
, verfolgen Sie einfachstate.top
, was Sie in einer lokalen Variablen sein möchten , und dann nur einmal am Ende descomponentDidUpdate
AufrufssetState
, wenn Ihre lokale Variable nicht übereinstimmtstate.top
. So wie es jetzt ist, werden Sie sofortstate.top
nach dem ersten erneuten Rendern zurückgesetzt, wodurch Sie in die Endlosschleife geraten.componentDidUpdate
in dieser Geige an .componentShouldUpdate
?Antworten:
Sie können
setState
innen verwendencomponentDidUpdate
. Das Problem ist, dass Sie irgendwie eine Endlosschleife erstellen, weil es keine Unterbrechungsbedingung gibt.Aufgrund der Tatsache, dass Sie Werte benötigen, die vom Browser nach dem Rendern der Komponente bereitgestellt werden, denke ich, dass Ihr Ansatz zur Verwendung
componentDidUpdate
korrekt ist. Sie müssen lediglich besser mit der Bedingung umgehen, die die auslöstsetState
.quelle
componentDidUpdate
undrender
stattdessen einfach nach Bedarf hinzugefügt werden kann .Die
componentDidUpdate
Unterschrift istvoid::componentDidUpdate(previousProps, previousState)
. Damit können Sie testen, welche Requisiten / Zustände verschmutzt sind und entsprechend anrufensetState
.Beispiel:
quelle
componentDidMount
hat keine Argumente und wird nur aufgerufen, wenn die Komponente erstellt wird, kann also nicht für den beschriebenen Zweck verwendet werden.componentDidMount
, und als ich die Antwort schrieb, kaskadierte der berühmte Name.componentDidUpdate(prevProps, prevState) { if ( prevState.x!== this.state.x) { //Do Something } }
Wenn Sie
setState
innerhalbcomponentDidUpdate
sie die Komponente aktualisiert, was zu einem Aufruf ancomponentDidUpdate
die anschließend ruftsetState
wieder in der Endlosschleife hängen bleibt . Sie sollten bedingt anrufensetState
und sicherstellen, dass die Bedingung, die den Anruf verletzt, irgendwann auftritt, z.Für den Fall , aktualisieren Sie nur die Komponente von Requisiten , um sie zu senden (es durch setState keine Aktualisierungen erfolgen, außer für den Fall innerhalb componentDidUpdate), können Sie rufen im
setState
InnerencomponentWillReceiveProps
stattcomponentDidUpdate
.quelle
getDerivedStateFromProps
.Dieses Beispiel hilft Ihnen, die React Life Cycle Hooks zu verstehen .
Sie können
setState
ingetDerivedStateFromProps
Verfahren alsostatic
und lösen das Verfahren nach Requisiten in änderncomponentDidUpdate
.In erhalten
componentDidUpdate
Sie den 3. Parameter, der von zurückkehrtgetSnapshotBeforeUpdate
.Sie können diesen Codesandbox-Link überprüfen
quelle
Ich würde sagen, dass Sie überprüfen müssen, ob der Status bereits denselben Wert hat, den Sie festlegen möchten. Wenn es dasselbe ist, macht es keinen Sinn, den Status für denselben Wert erneut festzulegen.
Stellen Sie sicher, dass Sie Ihren Status wie folgt einstellen:
quelle
Ich hatte ein ähnliches Problem, bei dem ich den ToolTip zentrieren muss. React setState in componentDidUpdate hat mich in eine Endlosschleife gebracht, ich habe versucht, Bedingung, dass es funktioniert. Aber ich fand, dass die Verwendung in Ref Callback mir eine einfachere und sauberere Lösung gab. Wenn Sie die Inline-Funktion für Ref Callback verwenden, werden Sie bei jedem Komponenten-Update mit dem Null-Problem konfrontiert. Verwenden Sie also die Funktionsreferenz im Ref-Rückruf und legen Sie dort den Status fest, der das erneute Rendern initiiert
quelle