2015-12-25 1 views
0

У меня есть два компонента: App и регистрационная формаReact.js - Рельсы: Установить государственные

Форма имеет два входа: Имя и Фамилию

Глядя на состоянии приложения в Dev. tools I see length: undefined и name: "name into". Я не получаю никаких ошибок, но мне не хватает фамилии.

Это происходит только в Rails. Я пробовал один и тот же код в среде без рельсов, и он отлично работает. Я использую этот драгоценный камень для React: драгоценный камень «реагируют поручни», «~> 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 }); 

}, 

Я могу видеть, регистрация объекта так, как я хочу. Я могу добавить столько уникальных регистраций в состояние приложения, но каждая регистрация имеет длину: undefined, name: «name», но отсутствует фамилия.

Если изменить установленное состояние на это:

this.setState({ registrations : registration }); 

Это дает мне единственную регистрацию имени и фамилии, но это не добавляет несколько регистраций. Он создает только одну регистрацию, которая обновляется каждый раз, когда я отправляю добавленную регистрационную форму.

ответ

0

this.state.registrations['registration-' + timestamp] = registration;

Вы, кажется, мутирует состояние непосредственно, на основе Реагировать Docs https://facebook.github.io/react/docs/component-api.html

NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate() . If mutable objects are being used and the logic cannot be implemented in shouldComponentUpdate() , calling setState() only when the new state differs from the previous state will avoid unnecessary re-renders.

Попробуйте клонировать текущее состояние затем использовать это в качестве аргумента.

// if array 
var clonedRegistration = this.state.registrations.slice(); 
clonedRegistration['registration-' + timestamp] = registration; 

this.setState({registrations: clonedRegistration}) 

или

this.setState({registrations: {['registration-'+ timestamp]: registration} }); 
+0

Спасибо за вашу помощь, но то, что вы предлагали не работать. – Asan

+0

сейчас я получаю эту ошибку: Uncaught TypeError: clonedRegistration.slice не является функцией – Asan

+0

@Asan попробуйте использовать второй вариант, ваши 'this.state.registrations' не являются массивом. – oobgam

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 }); 
}, 

Я бы посоветовал создать идентификатор где-то здесь, так как вы не используете фактический АЯКС вызов на рельсы дб:

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

Надеется, что это помогает,

+0

Спасибо, я дам вам знать результат, когда я попробую. – Asan