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 componentDidUpdate
cria 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>
);
}
});
componentDidUpdate
no presente violino .
componentShouldUpdate
?
setState
vai sempre provocar uma re-render. Em vez de verificarstate.top
e ligarsetState
várias vezes, basta rastrear o que você desejastate.top
fazer em uma variável local e, uma vez no final dacomponentDidUpdate
chamada,setState
apenas se sua variável local não corresponderstate.top
. Como está agora, você redefine imediatamentestate.top
após a primeira re-renderização, o que o coloca no loop infinito.