2015-12-25 1 views
1

Je travaille sur une simple application météore + réaction CRUD. Dans le code ci-dessous, mon this.setState() ne semble pas avoir d'effet sur <textarea>. Ainsi, lorsque je clique sur un lien et que le formulaire s'affiche de nouveau, la fonction clickLoadForm(appId) met correctement à jour l'état des éléments <input>, mais pas <textarea>, même si le fichier console.log indique clairement qu'il y a du contenu pour tous les champs. Qu'ai-je fait de mal?Réagir setState sur textarea ignoré

App = React.createClass({ 
    mixins: [ReactMeteorData], 

    getMeteorData() { 
    return { 
     applications: Applications.find({}, {sort: {createdAt: -1}}).fetch(), 
     currentApplication: Applications.findOne({_id:this.props.router.params.appid}, {sort: {createdAt: -1}}), 
    } 
    }, 
    getInitialState: function() { 
    return this.loadForm(this.props.router.params.appid); 
    }, 
    loadForm(appId) { 
    var currentApp = Applications.findOne({_id:appId}); 
    if(!currentApp) currentApp = {}; 
    return currentApp; 
    }, 
    clickLoadForm(appId) 
    { 
    var currentApp = this.loadForm(appId); 
    var state = new Object(); 
    var refs = this.refs; 
    Object.keys(refs).map(function(prop,index){ 
     state[prop] = typeof currentApp[prop] == 'undefined' ? "" : currentApp[prop]; 
    }); 
    console.log(state); 
    this.setState(state); 
    }, 
    renderListApplications() { 
    var _this = this; 
    return this.data.applications.map(function(applicationform,i) { 
     return <li key={"li"+i}><a onClick={_this.clickLoadForm.bind(_this,applicationform._id)} href={Meteor.absoluteUrl()+'application/' +applicationform._id} key={"a"+i}>Version {applicationform._id}</a></li>; 
    }); 
    }, 
    handleSubmit(event) { 
    event.preventDefault(); 
    var refs = this.refs; 
    var formVals = new Object(); 
    Object.keys(refs).map(function(prop, index){ 
     if(refs[prop].nodeName.match(/(INPUT|SELECT|TEXTAREA)/).length > 0) 
     formVals[prop] = refs[prop].value; 
    }); 

    Meteor.call("saveApplication", formVals); 

    }, 
    handleChange: function(e) { 
    if(!e.target.id) return; 
    if(typeof e.target.id == 'undefined') return; 
    var state = new Object(); 
    state[e.target.id] = e.target.value; 

    this.setState(state); 
    }, 
    render() { 
    return (
     <div className="container"> 
      <ul> 
      {this.renderListApplications()} 
      </ul> 
      <div>{JSON.stringify(this.data.currentApplication)}</div> 
      <form className="new-task" onSubmit={this.handleSubmit} > 
      <input ref="input_36" id="input_36" type="text" value={this.state.input_36} onChange={this.handleChange} /> 
      <input ref="input_37" id="input_37" type="text" value={this.state.input_37} onChange={this.handleChange} /> 
      <textarea ref="input_38" id="input_38" onChange={this.handleChange}>{this.state.input_38}</textarea> 
      <textarea ref="input_39" id="input_39" onChange={this.handleChange}>{this.state.input_39}</textarea> 
      <button type="submit">Submit</button> 
      </form> 
     </div> 
    ); 
    } 
}); 

Répondre

2

En fait, je l'ai compris. J'ai changé

<textarea ref="input_38" id="input_38" onChange={this.handleChange}>{this.state.input_38}</textarea> 
<textarea ref="input_39" id="input_39" onChange={this.handleChange}>{this.state.input_39}</textarea> 

à

<textarea ref="input_38" id="input_38" onChange={this.handleChange} value={this.state.input_38} /> 
<textarea ref="input_39" id="input_39" onChange={this.handleChange} value={this.state.input_39} /> 
+1

Great! Une note pour les futurs lecteurs: le raisonnement pour cela est mentionné [ici dans les docs] (http://facebook.github.io/react/docs/forms.html#why-textarea-value). –

+0

Et pour l'instant, je l'aime mieux, parce que quand je devais travailler avec le DOM, je trouvais incommode de vérifier parfois innerHTML, d'autres fois la valeur, d'autres fois les options [options.selectedIndex] .value etc ... . – John