React.js - Rails:设置状态

时间:2015-12-25 21:40:42

标签: ruby-on-rails reactjs react-rails

我有两个组成部分: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 });

这为我提供了一个名称和姓氏的注册,但它没有添加多个注册。它只创建一个注册,每次我提交添加注册表单时都会更新。

2 个答案:

答案 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);
} 

希望这有帮助,