首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ReactJs:更改状态以响应状态更改

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

Stack Overflow用户
提问于 2014-09-12 08:09:34
回答 2查看 21.2K关注 0票数 6

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

代码语言:javascript
运行
复制
[ basic ]
Hide Advanced...
[ advanced ]

如果您单击“隐藏高级”,则底部的高级将消失,这将更改为“显示高级”。这很简单,而且运行良好,在状态中有一个showAdvanced键,它控制文本和是否呈现高级输入。

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

因此,有人从外部调用cmp.setState({advanced: "20"}),然后我想显示高级;最直接的做法就是在我所处的状态下更新showAdvanced。然而,似乎没有一种方法可以更新某些状态以响应React中的其他状态更改。我可以想到一些行为略有不同的变通方法,但我真的想要这种特定的行为。

我应该把showAdvanced移到道具上吗,这有意义吗?你能改变道具来响应状态的改变吗?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-15 03:43:34

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

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

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

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

代码语言:javascript
运行
复制
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>
        );
    }
});

因此,当您第一次调用React.renderComponent(MyComponent({}), elem)时,组件将被挂载,而高级div将被隐藏。如果您单击组件内部的按钮,它将切换并显示。如果您需要强制组件从组件外部显示高级div,只需像这样再次调用render:React.renderComponent(MyComponent({showAdvanced: true}), elem),无论内部状态如何,它都会显示高级div。同样,如果你想从外部隐藏它,只需用showAdvanced: false调用它。

添加到上面的代码示例中的好处是,在componentWillReceiveProps内部调用setState不会导致另一个呈现周期,因为它会在调用render之前捕获并更改状态。有关更多信息,请查看此处的文档:http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops

不要忘记,在已经挂载的组件上再次调用renderComponent并不会再次挂载它,它只是告诉react更新组件的props,然后react将进行更改,运行组件的生命周期和渲染函数,并执行dom的差异魔术。

票数 9
EN

Stack Overflow用户

发布于 2014-09-12 08:47:33

在下面的注释中修改了答案。

我最初的错误答案是:

当收到新的状态或属性时,将运行生命周期函数componentWillUpdate。您可以在此处找到相关文档:http://facebook.github.io/react/docs/component-specs.html#updating-componentwillupdate

如果在调用外部setState时,在componentWillUpdate中将showAdvanced设置为true,则应该会得到所需的结果。

编辑:另一种选择是让对setState的外部调用包含处于新状态的showAdvanced: true

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25798803

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档