2016-09-23 55 views
1

我正在處理React中的表單。我在MatchForm組件中嵌套狀態,並使用不同輸入從狀態「綁定」值。我想要onChange函數來管理所有的輸入變化並將其傳遞給狀態。當我只有陣容輸入時,電流onChange功能起作用。但是當我添加其他輸入時,我不知道如何處理它。我應該如何命名輸入以及onChange函數應該如何處理所有輸入(沒有太多ifs)?React中的嵌套表單狀態和一個onChange函數

預先感謝您

class MatchForm extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     lineup: { 
     setter: '', 
     receiver1: '', 
     receiver2: '', 
     attacker: '', 
     blocker1: '', 
     blocker2: '', 
     libero: '' 
     }, 
     distribution: { 
     receiver1: 20, 
     receiver2: 20, 
     attacker: 20, 
     blocker1: 20, 
     blocker2: 20 
     }, 
     risk: 'normal', 
     default: false 
    }; 

    this.onChange = this.onChange.bind(this); 
    } 

    onChange(e) { 
    this.setState({lineup: { ...this.state.lineup, [e.target.name]:e.target.value } }) 
    } 

    render() { 
    return (
     <div> 
     { 
      Object.keys(this.state.lineup).map((el,i) => 
      <select 
       key={i} 
       name={el} 
       onChange={this.onChange} 
       value={this.state.lineup[el]} 
      > 
       <option value="" disabled>{el}</option> 
       <option value="Marian Noga">Marian Noga</option> 
       <option value="Janek Kowalski">Janek Kowalski</option> 
      </select> 
     ) 
     } 
     { 
      Object.keys(this.state.distribution).map((el,i) => 
      <Field 
       key={i} 
       field={el} 
       label={el} 
       type='number' 
       value={this.state.distribution[el]} 
       onChange={this.onChange} />  
      ) 
     } 
     <select 
      name="risk" 
      onChange={this.onChange} 
      value={this.state.risk} 
     > 
      <option value="" disabled>risk</option> 
      <option value="safe">safe</option> 
      <option value="normal">normal</option> 
      <option value="risk">risk</option> 
      </select> 
      <label><input name="default" type="checkbox" value={this.state.default} onChange={this.onChange} /> Set as default lineup</label> 
     </div> 
    ) 
    } 
} 

export default MatchForm 
+2

通常我會有多個onChange函數,每個函數都處理自己的輸入部分。一個試圖處理所有事情的大型函數可能看起來不那麼重複,但從長遠來看,它會使得重構表單變得更加困難。 –

回答

1

可以bindonChange功能每個字段的值不同:

onChange={this.onChange.bind(this, 'lineup', el)} 

然後,如果你寫你的onChange這樣的:

onChange(field, name, e) { 
    this.setState({[field]: { ...this.state[field], [name]:e.target.value } }); 
} 

您現在應該可以重複,對於每個字段。

2

如果它僅僅是一個控制的輸入,並沒有其他的UI邏輯,我做這樣簡單的事情,因爲這:

<input type="text" 
    name="email" 
    value={this.state.email} 
    onChange={e => this.setState({ email: e.target.value })} 
/> 
0

對於更復雜的用例,您也可以嘗試_.set。好消息是,單獨設置功能,可以下載作爲npm package

<input type="text" name="lineup.receiver1" onChange={handleChange} value={this.state.lineup.receiver1} />

import update from "lodash.set"; const handleChange = (ev) => { update(this.state, ev.target.name, ev.target.value) }

_.set還有更新嵌套的對象,它可以在我們的情況與HTML name財產使用更復雜的選項一個領域。