有关完整图片,请参阅此gist。
基本上我会有这种形式:
单击加号时,应显示另一行,其中包含日期和时间字段的下拉列表。
我可以创建代码来向表单添加输入,但是我遇到了单个组件(selectTimeInput
是一行)实际更新其值的问题。
onChange
中的MultipleDayTimeInput
正在接收正确的数据,它只是未更新的显示。我非常新的反应所以我不知道是什么导致显示器不更新....
我认为这是因为SelectTimeInput
渲染函数没有被调用,因为传入的props
没有被更新,但我不确定实现它的正确方法。
考虑到这一点,是否需要在setState
的{{1}}中调用onChange
,并且需要从MultipleDayTimeInput
删除已更改的输入并重新读取为了迫使渲染器射击......这对我来说似乎有点笨拙......
答案 0 :(得分:3)
更新状态输入的显示值时,需要使用this.setState
更改状态数据并使用新数据重新渲染。使用input.key = value不是正确的方法。
正确使用国家
你应该知道三件事 的setState()。不要直接修改状态
例如,这不会重新渲染a 成分://错了 this.state.comment ='你好';
相反,使用setState()://正确
this.setState({comment:' Hello'});
你唯一的地方 可以指定this.state是构造函数。
直接从Facebook阅读更多内容here
我实际上会建议你对代码进行一些重组。我们并不鼓励将组件作为您的州值的一部分。我建议在this.state.inputs中将不同的输入作为数据对象,并循环遍历数据并在render方法中构建每个显示方式。像这样:
假设你的this.state.inputs中有一个输入(假设你的输入是密钥访问的对象):
inputs = {
1: {
selectedTime: 0:00,
selectedValue: 2
}
}
在渲染中,执行以下操作:
render() {
let inputs = Object.keys(this.state.inputs).map((key) => {
let input = this.state.inputs[key]
return (<SelectTimeInput
key={key}
name={'option_' + key}
placeholder={this.props.placeholder}
options={this.props.options}
onChange={this.onChange.bind(this, key)}
timeValue={input.selectedTime}
selectValue={input.selectedValue}
/>)
)}
return (
<div>
<button className="button" onClick={this.onAddClick}><i className="fa fa-plus" /></button>
{ inputs }
</div>
);
}
注意我们如何在onChange上绑定密钥,以便我们知道要更新的输入。现在,在您的onChange
函数中,您只需使用setState设置正确的输入值:
onChange(event, key) {
this.setState({
inputs: Immutable.fromJS(this.state.inputs).setIn([`${key}`, 'selectedTime'], event.target.value).toJS()
// or
inputs: Object.assign(this.state.inputs, Object.assign(this.state.inputs[key], { timeValue: event.target.value }))
})
}
这个没有经过测试,但基本上这个Immutable语句将复制this.state.inputs并将匹配键的对象内的selectedTime值设置为event.target.value。状态现在更新,触发重新渲染,当您在渲染中再次循环输入时,您将使用新的时间值作为组件的timeValue
。
再次,使用Object.assign编辑,它没有经过测试,但了解更多[此处]。 2这个语句基本上是将一个新的timeValue值与this.state.inputs [key]对象合并,然后将该新对象与整个this.state.inputs对象合并。
这有意义吗?
答案 1 :(得分:0)
我修改了onChange
中的MultipleDayTimeInput
:
onChange(event) {
const comparisonKey = event.target.name.substring(event.target.name.length - 1);
const input = this.getInputState(comparisonKey);
input.selected = event.target.value;
input.display = this.renderTimeInput(input);
let spliceIndex = -1;
for (let i = 0; i < this.state.inputs.length; i++) {
const matches = inputFilter(comparisonKey)(this.state.inputs[i]);
if (matches) {
spliceIndex = i;
break;
}
}
if (spliceIndex < 0) {
throw 'error updating inputs';
}
this.setState({
inputs: [...this.state.inputs].splice(spliceIndex, 1, input)
});
}
关键点是:
// re render the input
input.display = this.renderTimeInput(input);
// set the state by copying the inputs and interchanging the old input with the new input....
this.setState({
inputs: [...this.state.inputs].splice(spliceIndex, 1, input)
});
考虑到这一点,input
是对this.state.inputs
输入的对象引用,所以实际上[...this.states.inputs]
已经足够了吗?