2017-03-28 59 views
0

這是我的代碼處理與迭代再現狀態輸入的變化......作出反應 - 通過陣列

class Module extends Component { 
     constructor() { 
      super() 

      this.state = { 
       inputs: [ 
        { type: 'text', placeholder: 'placeholder text', name: 'text1', id: 'text1', value: 'aaa' }, 
        { type: 'text', placeholder: 'another placeholder text', name: 'text2', id: 'text2', value: '' }, 
        { type: 'text', placeholder: 'third placeholder text', name: 'text3', id: 'text3', value: '' }, 
       ] 
      } 

      this.handleInputChange = this.handleInputChange.bind(this) 
      this.saveModule = this.saveModule.bind(this) 
     } 

     handleInputChange(event) { 
      this.setState ({ 
       [event.target.name]: event.target.value 
      }) 
     } 

     renderInput = (input) => { 
      return(
       <div key={ input.id }> 
        <input 
         type={ input.type } 
         name={ input.name } 
         placeholder={ input.placeholder } 
         onBlur={ this.saveModule } 
         value={ input.value } 
         onChange={ this.handleInputChange } 
        /> 
       </div> 
      ) 
     } 

     render() { 
      return (
       <div> 
        { this.state.inputs.map(this.renderInput) } 
       </div> 
      ) 
     } 
    } 

    export default Module 

我該如何處理其值從狀態以這種方式呈現的輸入的變化? 如果我有{this.state.input.value}它工作得很好,一旦我像這樣重構它,setState似乎並沒有達到它了。

任何想法? :)

非常感謝!

+0

首先你必須找到你將要工作的對象的索引。所以考慮'event.target.name'作爲過濾數組的條件。然後用這些更改創建一個新數組。並設置狀態。繼承人一個好方法如何做到這一點http://stackoverflow.com/a/36010124/7744070 –

回答

2

由於您要從中直接進行更改,因此您需要在onChange方法中執行更改。使用任何獨特屬性類似名稱或索引來標識哪個元素已被更改,迭代input array找到該輸入元素,然後更新該元素的值。在更新輸入數組中的值之後,也更新狀態輸入數組,當react重新呈現組件時,值將自動反映在UI中。

檢查工作代碼:

class Module extends React.Component { 
 
     constructor() { 
 
      super() 
 

 
      this.state = { 
 
       inputs: [ 
 
        { type: 'text', placeholder: 'placeholder text', name: 'text1', id: 'text1', value: 'aaa' }, 
 
        { type: 'text', placeholder: 'another placeholder text', name: 'text2', id: 'text2', value: '' }, 
 
        { type: 'text', placeholder: 'third placeholder text', name: 'text3', id: 'text3', value: '' }, 
 
       ] 
 
      } 
 

 
      this.handleInputChange = this.handleInputChange.bind(this) 
 
     } 
 

 
     handleInputChange(event) { 
 
      let inputs = this.state.inputs.slice(); 
 
      for(let i in inputs){ 
 
       if(inputs[i].name == event.target.name){ 
 
        inputs[i].value = event.target.value; 
 
        this.setState ({inputs}); 
 
        break; 
 
       } 
 
      } 
 
     } 
 

 
     renderInput = (input, i) => { 
 
      return(
 
       <div key={ input.id }> 
 
        <input 
 
         type={ input.type } 
 
         name={ input.name } 
 
         placeholder={ input.placeholder } 
 
         onBlur={ this.saveModule } 
 
         value={ input.value } 
 
         onChange={ this.handleInputChange } 
 
        /> 
 
       </div> 
 
      ) 
 
     } 
 

 
     render() { 
 
      return (
 
       <div> 
 
        { this.state.inputs.map(this.renderInput) } 
 
       </div> 
 
      ) 
 
     } 
 
    } 
 

 

 
ReactDOM.render(<Module/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div id='app'/>

+0

你能解釋你做了什麼?用更多的代碼替代一堆代碼對任何可能學習的人都沒有幫助React –

+0

@DarrenSweeney用適當的信息更新了答案。 –

+1

這個作品非常神奇,非常感謝你的解釋,這很有道理! :) – Majki

0

你必須首先創建一個新的狀態設定的狀態。

由於this.state是不可變的,所以通過僅使用spread operatorObject.assign修改舊狀態來創建新狀態。

This video是如何以不可變的方式更改javascript對象的很好參考。還有一個專門用於創建和修改不可變對象的庫,名爲immutable.js

Refer to this how to use immutable.js with react setState

(此代碼有經過測試)

class Module extends Component { 
    constructor() { 
     super() 

     this.state = { 
      inputs: [ 
       { type: 'text', placeholder: 'placeholder text', name: 'text1', id: 'text1', value: 'aaa' }, 
       { type: 'text', placeholder: 'another placeholder text', name: 'text2', id: 'text2', value: '' }, 
       { type: 'text', placeholder: 'third placeholder text', name: 'text3', id: 'text3', value: '' }, 
      ] 
     } 

     this.handleInputChange = this.handleInputChange.bind(this) 
     this.saveModule = this.saveModule.bind(this) 
    } 

    // change this to an arrow function 
    handleInputChange = (event) => { 
     const name = event.target.name; 
     const value = event.target.value; 
     const oldInputState = this.state.inputs.find(i => i.name === name); 
     // use the spread operator or Object.assign to create a brand new state object 
     this.setState({ 
      ..., 
      this.state, // copy everything from the old state 
      // expect change the `inputs` value 
      {inputs: [ // create a brand new array 
       ...this.state.inputs.filter(i => i.name !== name), 
       {...oldInputState, value} // replace old value with the new value 
       // refer to that video I included, it's a great explanation 
      ]} 
     }); 
    } 

    renderInput = (input) => { 
     return(
      <div key={ input.id }> 
       <input 
        type={ input.type } 
        name={ input.name } 
        placeholder={ input.placeholder } 
        onBlur={ this.saveModule } 
        value={ input.value } 
        onChange={ this.handleInputChange } 
       /> 
      </div> 
     ) 
    } 

    render() { 
     return (
      <div> 
       { this.state.inputs.map(this.renderInput) } 
      </div> 
     ) 
    } 
} 

export default Module 

祝你好運!

+1

我認爲,不需要使用帶'handleInputChange'的箭頭函數,他已經在構造函數中定義了綁定。 –

+0

@MayankShukla oops,你就在那裏 –