setState() à l'intérieur de componentDidUpdate()

Je suis en train d'écrire un script qui se déplace déroulante ci-dessous ou au-dessus de l'entrée en fonction de la hauteur de de liste déroulante et la position de l'entrée sur l'écran. Aussi, je veux modificateur de liste déroulante en fonction de sa direction.
Mais à l'aide de setState à l'intérieur de la componentDidUpdate crée une boucle infinie(ce qui est évident)

J'ai trouvé une solution en utilisant getDOMNode et configuration d'un nom de classe à déroulant directement, mais je pense qu'il devrait y avoir une meilleure solution à l'aide de Réagir outils. Quelqu'un peut-il m'aider?

Voici une partie du code du travail avec getDOMNode (je
un peu négligés logique de positionnement 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 (ce 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>
        );
    }
});
  • Je pense que le truc c'est que setState toujours déclencher un nouveau rendu. Plutôt que de vérifier state.top et de l'appel de setState plusieurs fois, il suffit de suivre ce que vous voulez state.top à être dans une variable locale, puis une fois à la fin de componentDidUpdate appel setState seulement si votre variable locale ne correspond pas state.top. Comme il est en ce moment, vous rétablir immédiatement le state.top après le premier rendu, qui vous met dans la boucle infinie.
  • Voir les deux implémentations différentes de componentDidUpdate dans ce violon.
  • damn it! variable locale résout tout le problème, comment n'avais-je pas pensé à elle par mysef! Merci!!!!
  • si vous écrivez une réponse, je vais le marquer comme correct
  • Je pense que vous devriez accepter la réponse ci-dessous. Si vous avez bien lu encore, je pense que vous trouverez cela répond à la question initiale suffisamment.
  • Pourquoi personne n'a suggéré de passer de l'état dans componentShouldUpdate?