2016-06-17 57 views
0

只是一點背景,我對JavaScript和Web開發真的很陌生,但一直很樂意在React上做一些教程。也是我第一次發佈在stackoverflow!處理onChange和設置輸入數組的狀態

我正在構建一個組件以顯示是/否問題列表,用戶必須通過選擇單選按鈕並在文本區域中添加一些註釋來進行響應。我不確定我應該如何設置使用map生成的輸入數組的狀態。

我有一個數組拿着我的問題:

var questions = [ 
    {id:"1", text:"Is the source up to date?"}, 
    {id:"2", text:"Question 2 placeholder"}, 
    {id:"3", text:"Question 3 placeholder"}, 
] 

,這裏是我的(未完成)成分:

var QuestionList = React.createClass({ 
    getInitialState: function() { 
     return { 
      commentText: "", 
     } 
    }, 

    onUpdateComments: function (e) { 
     this.setState({ 
      commentText: e.target.value 
     }); 
    }, 
    render: function() { 
     var QuestionLines = this.props.questions.map(function(question) { 
      return (
       <div key={question.id}> 
        <div> 
         <div> 
          {question.text} 
         </div> 
         <label> 
          <input type="radio" name={question.id} value = {question.id+'Y'}/>Yes 
         </label> 
         <label> 
          <input type="radio" name={question.id} value = {question.id+'N'}/>No 
         </label> 
        </div> 
        <div> 
         <textarea 
          name = {question.id} 
          onChange = {this.onUpdateComments} 
          placeholder="Enter comments here" 
          value={this.state.commentText} /> 
        </div> 
       </div> 
      ); 
     }, this); 
     return (
      <div> 
       {QuestionLines} 
      </div> 
     ) 
    } 
}); 

的應用程序現在會顯示在所有3個文本域相同的文字,我可以看到這是因爲我將textarea的所有更改存儲在相同的commmentText狀態中。但是,我真的很難將我需要做的事情分離出來並完成這項工作。任何幫助將不勝感激。

另外,正如我所提到的,我對這個超新的東西,所以如果有什麼關於我如何構建我的組件,請讓我知道。

謝謝!

回答

0

我會做這樣的事情:

var QuestionList = React.createClass({ 
    getInitialState: function() { 
     return { comments: {} } //set internal state comment as an empty object 
    }, 

    onUpdateComments: function (id, e) { 

     /* 
      you can modify your state only using setState. But be carefull when trying to grab actual state and modify it's reference. 
      So, the best way is to create a new object (immutable pattern), and one way of doing that is to use Object.assign 
     */ 
     var comments = Object.assign({}, this.state.comments); 

     /* set, for instance, comment[1] to "some text" */ 
     comments[id] = e.target.value; 

     /* set the state to the new variable */ 
     this.setState({comments: comments}); 


    }, 
    render: function() { 
     var QuestionLines = this.props.questions.map(function(question) { 

      /* grab the comment for this ID. If undefined, set to empty */ 
      var comment = this.state.comments[question.id] || ""; 

      return (
       <div key={question.id}> 
        <div> 
         <div> 
          {question.text} 
         </div> 
         <label> 
          <input type="radio" name={question.id} value = {question.id+'Y'}/>Yes 
         </label> 
         <label> 
          <input type="radio" name={question.id} value = {question.id+'N'}/>No 
         </label> 
        </div> 
        <div> 
         <textarea 
          name = {question.id} 
          onChange = {this.onUpdateComments.bind(this,question.id)} 
          placeholder="Enter comments here" 
          value={comment} /> 
        </div> 
       </div> 
      ); 
     }, this); 
     return (
      <div> 
       {QuestionLines} 
      </div> 
     ) 
    } 
}); 
+0

謝謝!這工作完美。 – wongtam

0

只需設置commentText作爲一個對象:

var QuestionList = React.createClass({ 
    getInitialState: function() { 
     return { 
      commentText: {}, 
     } 
    }, 

    onUpdateComments: function (e) { 

     // Note that e.target.name is question.id 
     var target = e.target; 
     this.state.commentText[target.name] = target.value; 
     this.forceUpdate(); 
    }, 
    render: function() { 
     var QuestionLines = this.props.questions.map(function(question) { 

      var id = question.id; // store id 

      return (
       <div key={id}> 
        <div> 
         <div> 
          {question.text} 
         </div> 
         <label> 
          <input type="radio" name={id} value = {id+'Y'}/>Yes 
         </label> 
         <label> 
          <input type="radio" name={id} value = {id+'N'}/>No 
         </label> 
        </div> 
        <div> 
         <textarea 
          name = {id} 
          onChange = {this.onUpdateComments} 
          placeholder="Enter comments here" 
          value={this.state.commentText[id]} /> 
        </div> 
       </div> 
      ); 
     }, this); 
     return (
      <div> 
       {QuestionLines} 
      </div> 
     ) 
    } 
}); 

見差異onUpdateCommentsvalue={this.state.commentText[id]}之間。

注: 如果使用通天編譯代碼,你可以寫onUpdateComments這樣的:

onUpdateComments: function (e) { 

    // Note that e.target.name is question.id 
    var target = e.target; 
    this.setState(function(previousState) { 
     return { 
     commentText: { 
      ...previousState.commentText, 
      [target.name]: target.value 
     } 
     } 
    }); 
}, 
0

一個解決辦法是有一個commentTextStore對象,其中的鍵(屬性)是commentIds和那麼你有每個問題的文本區域寫入相應的commentId值。

相關問題