setState() inside of componentDidUpdate()

2022-08-30 02:35:23

我正在编写一个脚本,该脚本根据下拉列表的高度和输入在屏幕上的位置将下拉列表移动到输入下方或上方。另外,我想根据其方向将修饰符设置为下拉列表。但是使用内部会创建一个无限循环(这是显而易见的)setStatecomponentDidUpdate

我已经找到了使用和设置classname直接下拉列表的解决方案,但我觉得使用React工具应该有更好的解决方案。任何人都可以帮助我吗?getDOMNode

这里是工作代码的一部分(我有点忽略了定位逻辑来简化代码)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>
        );
    }
});

答案 1

您可以在 里面使用。问题是,你以某种方式创建了一个无限循环,因为没有中断条件。setStatecomponentDidUpdate

基于您需要在呈现组件后由浏览器提供的值这一事实,我认为您关于使用的方法是正确的,它只需要更好地处理触发.componentDidUpdatesetState


答案 2

签名为 。有了这个,你将能够测试哪些道具/状态是脏的,并相应地调用。componentDidUpdatevoid::componentDidUpdate(previousProps, previousState)setState

例:

componentDidUpdate(previousProps, previousState) {
    if (previousProps.data !== this.props.data) {
        this.setState({/*....*/})
    }
}