我正在处理多阶段表单,该表单通过基于this guide的AJAX获取一些中间数据。我有一个奇怪的问题,React并没有将新道具传递给组件。
// MyForm.js.jsx
var MyForm = React.createClass({
render: function() {
switch(this.state.stage) {
case 1:
return <InitialFields
nextStage={this.nextStage}
save={this.save}
/>
case 2:
return <ChoiceFields
title="Choose first thing:"
field="first_id"
options={this.state.firstChoices}
nextStage={this.nextStage}
save={this.save}
/>
case 3:
return <ChoiceFields
title="Choose second thing:"
field="second_id"
options={this.state.secondChoices}
nextStage={this.nextStage}
save={this.save}
/>
}
}
// etc ...
});
ChoiceFields.js.jsx:
var ChoiceFields = React.createClass({
render: function() {
console.log(this.state);
var options = this.setOptions();
return (
<div className="choiceFields">
<h1>{this.props.title}</h1>
<SearchBar onChange={this.onSearch} />
<div className="btn-group">{options}</div>
<NextButton next={this.saveAndContinue} text="Set Default Values" />
</div>
);
},
setOptions: function() {
var buttons = this.state.options;
return buttons.map(function(choice) {
return (
<ChoiceButton key={choice.id} title={choice.name}
description={choice.description} id={choice.id}
makeSelection={this.selectButton} selected={choice.selected}
/>
);
}.bind(this));
}
});
当状态从1前进到2时,它会毫无问题地呈现ChoiceField。当状态从2前进到3时,它会呈现新标题,但options
道具尽管给出了不同的对象,但仍保持不变。
是否有某种方法可以强制React更新道具,或以其他方式重新呈现ChoiceFields
对象?
- UPDATE -
我正在将this.props.options
复制到this.state.options
,并使用状态来跟踪是否选择了某个选项。根据@ superfell的建议,我将对象数组保存在props
中,并计算在render方法中选择了哪一个。这解决了这个问题。
答案 0 :(得分:2)
根据这些注释,您要将道具复制到getInitialState中的ChoiceFields组件中。当道具更新时,getInitialState不会再次被调用,因此您将不再看待陈旧状态。您可以向ChoiceFields添加componentWillReceiveProps函数,该函数可以从新道具更新状态。或者你可以重构不要将道具复制到州,因为那是一个特定的anti-pattern called out by React。
答案 1 :(得分:1)
您可以使用的另一个选项是为您的ChoiceField
变体提供不同的密钥,因此React会知道它们是不同的实例,并且当您在后续渲染中交换它们时,它们将获得完整的组件生命周期: / p>
case 2:
return <ChoiceFields
key="first"
title="Choose first thing:"
field="first_id"
options={this.state.firstChoices}
nextStage={this.nextStage}
save={this.save}
/>
case 3:
return <ChoiceFields
key="second"
title="Choose second thing:"
field="second_id"
options={this.state.secondChoices}
nextStage={this.nextStage}
save={this.save}
/>
React.js and Dynamic Children - Why the Keys are Important很好地解释了正在发生的事情以及相关文档的链接。