Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ReactJs:更改状态以响应状态更改_Javascript_State_Reactjs - Fatal编程技术网

Javascript ReactJs:更改状态以响应状态更改

Javascript ReactJs:更改状态以响应状态更改,javascript,state,reactjs,Javascript,State,Reactjs,我有一个带有输入的React组件和一个可选的“高级输入”: 如果单击“隐藏高级”,则底部的高级将消失,而“隐藏高级”将变为“显示高级”。这很简单,工作正常,状态中有一个showAdvanced键控制文本以及是否呈现高级输入 但是,外部JS代码可能会更改advanced的值,在这种情况下,如果[advanced]输入当前处于隐藏状态,并且该值与默认值不同,我希望显示它。但是,用户应该能够单击“隐藏高级”再次关闭它 因此,有人外部调用cmp.setState({advanced:“20”}),然后我

我有一个带有输入的React组件和一个可选的“高级输入”:

如果单击“隐藏高级”,则底部的高级将消失,而“隐藏高级”将变为“显示高级”。这很简单,工作正常,状态中有一个
showAdvanced
键控制文本以及是否呈现高级输入

但是,外部JS代码可能会更改advanced的值,在这种情况下,如果[advanced]输入当前处于隐藏状态,并且该值与默认值不同,我希望显示它。但是,用户应该能够单击“隐藏高级”再次关闭它

因此,有人外部调用
cmp.setState({advanced:“20”})
,然后我想显示advanced;最简单的方法就是在我的状态下更新
showAdvanced
。但是,似乎没有一种方法可以更新某些状态以响应React中的其他状态更改。我可以想出一些行为稍有不同的变通方法,但我真的希望有这种特定的行为


我应该把showAdvanced换成道具吗,这有意义吗?你能改变道具来回应状态的改变吗?谢谢。

在下面的评论中修改了答案


我最初的错误答案是:

当收到新状态或道具时,生命周期功能组件将更新。您可以在此处找到相关文档:

如果在调用外部
setState
时,然后在
组件willupdate
中将
showAdvanced
设置为
true
,则应获得所需的结果


编辑:另一个选项是让对
setState
的外部调用在其新状态下包含
showAdvanced:true

好的,首先,您提到组件外部的第三方可能会调用
cmp.setState()
?这是一个巨大的问题。一个组件应该只调用它自己的setState函数——外部的任何东西都不应该访问它

另一件要记住的事情是,如果你试图再次改变状态以回应状态的改变,这意味着你做错了什么

当你以这种方式构建事物时,它会使你的问题比它需要的困难得多。原因是,如果您接受任何外部事物都不能设置组件的状态,那么基本上您唯一的选择就是允许外部事物更新组件的道具,然后在组件内部对它们做出反应。这简化了问题

因此,例如,您应该考虑让以前调用的任何外部对象重新调用组件上的
cmp.setState()
,而不是调用
React.renderComponent
,提供新的属性或属性值,例如
showAdvanced
设置为
true
。然后,您的组件可以在
componentWillReceiveProps
中对此做出反应,并相应地设置其状态。下面是一段示例代码:

var MyComponent = React.createClass({
    getInitialState: function() {
        return {
            showAdvanced: this.props.showAdvanced || false
        }
    },
    componentWillReceiveProps: function(nextProps) {
        if (typeof nextProps.showAdvanced === 'boolean') {
            this.setState({
                showAdvanced: nextProps.showAdvanced
            })
        }
    },
    toggleAdvancedClickHandler: function(e) {
        this.setState({
            showAdvanced: !this.state.showAdvanced
        })
    },
    render: function() {
        return (
            <div>
                <div>Basic stuff</div>
                <div>
                    <button onClick={this.toggleAdvancedClickHandler}>
                        {(this.state.showAdvanced ? 'Hide' : 'Show') + ' Advanced'}
                    </button>
                </div>
                <div style={{display: this.state.showAdvanced ? 'block' : 'none'}}>
                    Advanced Stuff
                </div>
            </div>
        );
    }
});
var MyComponent=React.createClass({
getInitialState:函数(){
返回{
showAdvanced:this.props.showAdvanced | | false
}
},
组件将接收道具:函数(下一步){
if(typeof nextrops.showAdvanced==='boolean'){
这是我的国家({
showAdvanced:nextrops.showAdvanced
})
}
},
ToggLeadAdvancedClickHandler:函数(e){
这是我的国家({
showAdvanced:!this.state.showAdvanced
})
},
render:function(){
返回(
基本材料
{(this.state.showAdvanced?'Hide':'Show')+'Advanced'}
高级材料
);
}
});
因此,当您第一次调用
React.renderComponent(MyComponent({}),elem)
时,组件将装入,高级div将被隐藏。如果单击组件内的按钮,它将切换并显示。如果需要强制组件从组件外部显示高级div,只需再次调用render,如下所示:
React.renderComponent(MyComponent({showAdvanced:true}),elem)
,它将显示它,而不管内部状态如何。同样,如果您想从外部隐藏它,只需使用
showAdvanced:false
调用它即可

上述代码示例的额外好处是,在
组件WillReceiveProps
内部调用
setState
不会导致另一个渲染周期,因为它捕获并更改调用
渲染之前的状态。有关更多信息,请查看此处的文档:


不要忘记,在已安装的组件上再次调用
renderComponent
不会再次安装它,它只是告诉react更新组件的
道具,然后react将进行更改,运行组件的生命周期和渲染功能,并执行dom diffing magic。

文档中说您不能从组件WillUpdate中使用setState,这就是我首先遇到问题的原因。我曾考虑让外部JS处理状态,但这会将特定于组件的逻辑推给不需要处理状态的用户。啊,这是真的。您可能希望通过
props
设置其初始值。与
高级\u文本
相同。然后,如果另一个组件设置了
advanced_text
状态,则在
render
中使用如下逻辑:
this.state.advanced_text | this.props.initial_advanced_text
。如果设置了
this.state.Advanced_text
,您也可以隐藏
hide Advanced
按钮。根据另一个状态设置一个状态听起来像是反模式。为什么不检查渲染方法中的
advanced
状态?是否有
var MyComponent = React.createClass({
    getInitialState: function() {
        return {
            showAdvanced: this.props.showAdvanced || false
        }
    },
    componentWillReceiveProps: function(nextProps) {
        if (typeof nextProps.showAdvanced === 'boolean') {
            this.setState({
                showAdvanced: nextProps.showAdvanced
            })
        }
    },
    toggleAdvancedClickHandler: function(e) {
        this.setState({
            showAdvanced: !this.state.showAdvanced
        })
    },
    render: function() {
        return (
            <div>
                <div>Basic stuff</div>
                <div>
                    <button onClick={this.toggleAdvancedClickHandler}>
                        {(this.state.showAdvanced ? 'Hide' : 'Show') + ' Advanced'}
                    </button>
                </div>
                <div style={{display: this.state.showAdvanced ? 'block' : 'none'}}>
                    Advanced Stuff
                </div>
            </div>
        );
    }
});