Piszę skrypt, który przesuwa się poniżej lub powyżej wejścia w zależności od wysokości rozwijanego menu i pozycji wejścia na ekranie. Chcę też ustawić modyfikator na rozwijany zgodnie z jego kierunkiem. Ale użycie setState
wewnątrz componentDidUpdate
tworzy nieskończoną pętlę (co jest oczywiste)
Znalazłem rozwiązanie w używaniu getDOMNode
i ustawianiu nazwy klasy bezpośrednio na liście rozwijanej, ale uważam, że powinno być lepsze rozwiązanie przy użyciu narzędzi React. Czy ktoś może mi pomóc?
Oto część działającego kodu z getDOMNode
(m.in. trochę zaniedbaną logiką pozycjonowania w celu uproszczenia kodu)
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>
);
}
});
a oto kod z setstate (który tworzy nieskończoną pętlę)
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
w tym skrzypce .
componentShouldUpdate
?
setState
że zawsze spowoduje to ponowne renderowanie. Zamiast sprawdzaćstate.top
i wywoływaćsetState
wiele razy, po prostu śledź, co chceszstate.top
znaleźć w zmiennej lokalnej, a następnie raz na końcucomponentDidUpdate
wywołaniasetState
tylko wtedy, gdy zmienna lokalna nie pasujestate.top
. W tej chwili resetujesz się natychmiaststate.top
po pierwszym ponownym renderowaniu, co umieszcza cię w nieskończonej pętli.