setState() 在 componentDidUpdate() 内部 [英] setState() inside of componentDidUpdate()

查看:40
本文介绍了setState() 在 componentDidUpdate() 内部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个脚本,它根据下拉菜单的高度和屏幕上输入的位置在输入下方或上方移动下拉菜单.此外,我想根据其方向将修饰符设置为下拉列表.但是在 componentDidUpdate 内部使用 setState 会创建一个无限循环(这很明显)

I'm writing a script which moves dropdown below or above input depending on height of dropdown and position of the input on the screen. Also I want to set modifier to dropdown according to its direction. But using setState inside of the componentDidUpdate creates an infinite loop(which is obvious)

我已经找到了使用 getDOMNode 并直接将 classname 设置为 dropdown 的解决方案,但我觉得使用 React 工具应该有更好的解决方案.有人可以帮我吗?

I've found a solution in using getDOMNode and setting classname to dropdown directly, but i feel that there should be a better solution using React tools. Can anybody help me?

这是带有 getDOMNode 的工作代码的一部分(我稍微忽略定位逻辑以简化代码)

Here is a part of working code with getDOMNode (i a little bit neglected positioning logic to simplify code)

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 的代码(它会创建一个无限循环)

and here is code with setstate (which creates an infinite loop)

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 中使用 setState.问题在于,您以某种方式创建了一个无限循环,因为没有中断条件.

You can use setStateinside componentDidUpdate. The problem is that somehow you are creating an infinite loop because there's no break condition.

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

Based on the fact that you need values that are provided by the browser once the component is rendered, I think your approach about using componentDidUpdate is correct, it just needs better handling of the condition that triggers the setState.

这篇关于setState() 在 componentDidUpdate() 内部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆