我有两个组成部分:App和Registration Form
表单有两个输入:名称和姓氏
查看开发中的App状态。工具我看到长度:未定义和名称:"名称已输入"。我没有收到任何错误,但我错过了姓氏。
这只发生在Rails中。我在非rails环境中尝试了相同的代码,它工作正常。我将这个宝石用于React:gem' react-rails','〜> 1.5.0'并运行Rails 4.2.4
var App = React.createClass({
getInitialState : function(){
return {
registrations: {}
}
},
addRegistration : function(registration){
// create unique id
var timestamp = (new Date()).getTime();
// update state
this.state.registrations['registration-' + timestamp] = registration;
//set the state
this.setState({ registrations : this.state.registrations });
},
render : function(){
return (
<RegistrationForm addRegistration={this.addRegistration}/>
)
}
});
var RegistrationForm = React.createClass({
createRegistration : function(event){
// prevent default
event.preventDefault();
// take data from form and create object
var registration = {
name : this.refs.name.value,
lastname : this.refs.lastname.value
}
// Add registration to App Object
this.props.addRegistration(registration);
this.refs.registrationForm.reset();
//console.log(registration);
},
render : function(){
return (
<div className="col-sm-12">
<form action="" className="form" ref="registrationForm" onSubmit={this.createRegistration}>
<div className="form-group">
<label >Name</label>
<input className="form-control" ref="name"/>
</div>
<div className="form-group">
<label >Last Name</label>
<input className="form-control" ref="lastname"/>
</div>
<div>
<button className="btn btn-primary">Submit</button>
</div>
</form>
</div>
)
}
});
App = React.createFactory(App)
我尝试做的是根据时间戳为每个注册提供唯一的ID号。
当我登录时记录以下内容:
addRegistration : function(registration){
// create unique id
var timestamp = (new Date()).getTime();
// update state
this.state.registrations['registration-' + timestamp] = registration;
//set the state
this.setState({ registrations : this.state.registrations });
},
我可以按照我想要的方式查看注册对象。我可以向App状态添加任意数量的唯一注册,但每个注册都有长度:undefined,name:&#34; name&#34; ,但它错过了姓氏。
如果我将设置状态更改为:
this.setState({ registrations : registration });
这为我提供了一个名称和姓氏的注册,但它没有添加多个注册。它只创建一个注册,每次我提交添加注册表单时都会更新。
答案 0 :(得分:0)
this.state.registrations['registration-' + timestamp] = registration;
您似乎是根据React Docs https://facebook.github.io/react/docs/component-api.html
直接改变状态不要直接改变this.state,因为之后调用
setState()
可能 替换你所做的突变。将this.state
视为好像 不可变的。
setState()
不会立即改变this.state
但是 创建待定状态转换。调用后访问this.state 此方法可能会返回现有值。没有 保证调用setState和调用的同步操作 为获得业绩增长而受到批评。
setState()将始终触发a 除非实现条件渲染逻辑,否则重新渲染
shouldComponentUpdate()
。如果正在使用可变对象而且 逻辑无法在shouldComponentUpdate()
中实现,即调用setState()
仅当新状态与先前状态不同时 将避免不必要的重新渲染。
尝试克隆当前状态,然后将其用作参数。
// if array
var clonedRegistration = this.state.registrations.slice();
clonedRegistration['registration-' + timestamp] = registration;
this.setState({registrations: clonedRegistration})
或
this.setState({registrations: {['registration-'+ timestamp]: registration} });
答案 1 :(得分:0)
我认为道路的答案很接近。
首先将初始状态设置为数组。
getInitialState: function(){
return { registrations: []}
}
你的addRegistration函数
addRegistration : function(registration){
我认为这就是你所缺少的:
//getting current state
var oldRegistrations = this.state.registrations;
否则我相信你一遍又一遍地更新同样的东西,而不是添加一个新的注册对象。然后推送您的注册。您应该设置时间戳
// update state
oldRegistrations.push(registration);
var registrations = oldRegistrations;
//set the state
this.setState({ registrations : registrations });
},
我建议在这里创建id,因为你没有使用对rails db的实际ajax调用:
var registration = {
name : this.refs.name.value,
lastname : this.refs.lastname.value
id: (new Date()).getTime();
}
我不确定我是否理解您关于表单价值的问题,或者您是否遇到过问题。但如果你是我认为做这样的事情可能会有所帮助:
<input type='text' className='form-control'
placeholder='Name' name='name'
value={this.state.name} onChange={this.handleChange} >
</input>
<input type='text' className='form-control'
placeholder='Last Name' name='last name'
value={this.state.last_name} onChange={this.handleChange} >
</input>
然后在同一个组件中实现一个handleChange函数,以不断处理表单的值onChange。这应该是这样的:
handleChange: function(e) {
var name = e.target.name;
var obj = {};
obj[name] = e.target.value;
this.setState(obj);
}
希望这有帮助,