ReactJs:响应状态变化改变状态

时间:2014-09-12 00:09:34

标签: javascript state reactjs

我有一个带输入的React组件,以及一个可选的"高级输入":

[ basic ]
Hide Advanced...
[ advanced ]

如果您点击"隐藏高级",它将更改为"显示高级"底部的高级消失。这很简单,工作正常,状态中有一个showAdvanced键来控制文本以及是否呈现高级输入。

但是,外部JS代码可能会更改高级值,在这种情况下,我想显示[高级]输入,如果它当前被隐藏且值不同于默认值。用户应该能够点击"隐藏高级"然而,再次关闭它。

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

我应该将showAdvanced移动到道具,这有意义吗?你能改变道具以响应状态变化吗?感谢。

2 个答案:

答案 0 :(得分:9)

首先,您提到组件外的第三方可能会拨打cmp.setState()?这是一个巨大的反应禁忌。组件应该只调用它自己的setState函数 - 外面没有任何东西可以访问它。

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

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

因此,举例来说,您应该查看曾经调用cmp.setState()的任何外部事件,而是再次调用组件上的React.renderComponent,提供新的prop或prop值,例如{{1}设置为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> ); } }); 时,组件将挂载,高级div将被隐藏。如果单击组件内的按钮,它将切换并显示。如果您需要强制组件显示组件外部的高级div,则只需再次调用render:React.renderComponent(MyComponent({}), elem)并显示它,无论内部状态如何。同样,如果您想将其隐藏在外面,只需使用React.renderComponent(MyComponent({showAdvanced: true}), elem)调用它。

在上面的代码示例中添加了奖励,即在showAdvanced: false内调用setState不会导致另一个渲染周期,因为它会在调用componentWillReceiveProps之前捕获并更改状态。有关详细信息,请查看此处的文档:http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops

不要忘记在已安装的组件上再次调用render不会再次安装它,它只是告诉您更新组件的renderComponent并做出反应然后进行更改,运行生命周期和渲染组件的功能,并做它不同的魔法。

答案 1 :(得分:0)

以下评论中修改了答案。


我最初的错误回答:

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

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

编辑:另一种选择是让setState的外部呼叫包含showAdvanced: true处于新状态。