J'écris un script qui déplace la liste déroulante en dessous ou au-dessus de l'entrée en fonction de la hauteur de la liste déroulante et de la position de l'entrée sur l'écran. Je souhaite également définir le modificateur sur la liste déroulante en fonction de sa direction. Mais utiliser à l' setState
intérieur de componentDidUpdate
crée une boucle infinie (ce qui est évident)
J'ai trouvé une solution en utilisant getDOMNode
et en définissant le nom de classe directement sur la liste déroulante, mais je pense qu'il devrait y avoir une meilleure solution en utilisant les outils React. Quelqu'un peut-il m'aider?
Voici une partie du code de travail avec getDOMNode
(une logique de positionnement un peu négligée pour simplifier le code)
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>
);
}
});
et voici le code avec setstate (qui crée une boucle infinie)
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>
);
}
});
componentDidUpdate
dans ce violon .
componentShouldUpdate
?
setState
cela déclenchera toujours un nouveau rendu. Plutôt que de vérifierstate.top
et d'appelersetState
plusieurs fois, suivez simplement ce que vous voulezstate.top
être dans une variable locale, puis une fois à la fin de l'componentDidUpdate
appelsetState
uniquement si votre variable locale ne correspond passtate.top
. Dans l'état actuel des choses, vous réinitialisez immédiatementstate.top
après le premier rendu, ce qui vous place dans la boucle infinie.