Estou escrevendo um script que move a lista suspensa abaixo ou acima da entrada, dependendo da altura da lista suspensa e da posição da entrada na tela. Também quero definir modificador para suspenso de acordo com sua direção. Mas usandosetState dentro do componentDidUpdatecria um loop infinito (o que é óbvio)
Eu encontrei uma solução ao usar getDOMNode e definir o nome da classe para o menu suspenso diretamente, mas acho que deve haver uma solução melhor usando as ferramentas React. Alguém pode me ajudar?
Aqui está uma parte do código de trabalho com getDOMNode(uma lógica de posicionamento um pouco negligenciada para simplificar o código)
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>
);
}
});
e aqui está o código com setstate (que cria um loop infinito)
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>
);
}
});
componentDidUpdateno presente violino .
componentShouldUpdate?
setStatevai sempre provocar uma re-render. Em vez de verificarstate.tope ligarsetStatevárias vezes, basta rastrear o que você desejastate.topfazer em uma variável local e, uma vez no final dacomponentDidUpdatechamada,setStateapenas se sua variável local não corresponderstate.top. Como está agora, você redefine imediatamentestate.topapós a primeira re-renderização, o que o coloca no loop infinito.