我正在写一个脚本,根据下拉菜单的高度和输入在屏幕上的位置将下拉菜单移到输入的下方或上方。我还想根据下拉菜单的方向设置修改器。但是在componentDidUpdate
内部使用setState
会创建一个无限循环(这是显而易见的)
我已经找到了一个使用getDOMNode
并直接将classname设置为dropdown的解决方案,但是我觉得应该有一个使用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>
);
}
});
9条答案
按热度按时间kq0g1dla1#
你可以在
componentDidUpdate
中使用setState
,问题是你创建了一个无限循环,因为没有break条件。基于这样一个事实,即一旦呈现组件,您就需要浏览器提供的值,我认为您使用
componentDidUpdate
的方法是正确的,它只需要更好地处理触发setState
的条件。6l7fqoea2#
componentDidUpdate
的签名是void::componentDidUpdate(previousProps, previousState)
。使用这个签名,您将能够测试哪些属性/状态是脏的,并相应地调用setState
。示例:
bkhjykvo3#
如果您在
componentDidUpdate
中使用setState
,它将更新组件,导致调用componentDidUpdate
,componentDidUpdate
随后再次调用setState
,从而导致无限循环。您应该有条件地调用setState
,并确保违反调用的条件最终发生,例如:如果您只是通过向组件发送属性来更新组件(它不是通过setState更新的,componentDidUpdate内部的情况除外),则可以在
componentWillReceiveProps
中调用setState
,而不是componentDidUpdate
。gzjq41n44#
此示例将帮助您了解React生命周期挂接。
您可以在
getDerivedStateFromProps
方法中使用setState
,即static
,并在componentDidUpdate
中的属性发生变化后触发该方法。在
componentDidUpdate
中,您将获得从getSnapshotBeforeUpdate
返回的第三个参数。您可以检查此codesandbox link
cwtwac6a5#
我会说,您需要检查state是否已经具有您试图设置的相同值,如果是相同的,则没有必要为相同的值再次设置state。
请确保按如下方式设置您的状态:
5jvtdoz26#
当循环中没有中断条件时,在ComponentDidUpdate中使用此. setState会创建无限循环。您可以使用redux在if语句中设置变量true,然后在条件中设置变量false,这样它就可以工作。
就像这样。
ftf50wuq7#
我遇到过类似的问题。请将componentDidUpdate设置为一个箭头函数。应该可以。
2jcobegt8#
我遇到过一个类似的问题,我必须将工具提示居中。componentDidUpdate中的React setState确实让我陷入了无限循环,我尝试了它工作的条件。但我发现在ref回调中使用给了我更简单和干净的解决方案,如果您使用内联函数进行ref回调,则每次组件更新都将面临null问题。因此,在ref回调中使用函数引用并在那里设置状态。这将启动重新渲染
rjzwgtxy9#
您可以在componentDidUpdate内使用setState