ドロップダウンの高さと画面上の入力の位置に応じて、ドロップダウンを入力の下または上に移動するスクリプトを書いています。また、修飾子をその方向に応じてドロップダウンに設定したいと思います。しかし、setState
内部で使用componentDidUpdate
すると無限ループが発生します(これは明らかです)
getDOMNode
classnameを直接使用してドロップダウンに設定することで解決策を見つけましたが、Reactツールを使用するより良い解決策があるはずです。誰かが私を助けてくれますか?
以下は、機能するコードの一部ですgetDOMNode
(コードを簡略化するためにポジショニングロジックを少し無視しています)。
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>
);
}
});
そしてこれがsetstateを含むコードです(これは無限ループを作成します)
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>
);
}
});
componentShouldUpdate
ですか?
setState
が常に再レンダリングをトリガーすることだと思います。複数回チェックstate.top
して呼び出すのではなく、ローカル変数に含めsetState
たいものを追跡し、ローカル変数が一致しない場合にのみstate.top
、componentDidUpdate
呼び出しの最後に一度だけ追跡します。現在の状態では、最初の再レンダリングの直後にリセットされ、無限ループに入ります。setState
state.top
state.top