2017-08-09 4 views
0

追加/削除ボタンをクリックして行を追加/削除できるフォームを作成したいと考えています。今私の問題は、削除ボタンは、削除ボタンが配置されている行ではなく、最後の行を削除することができることです。配列delete演算子を使用すると、目的の行が削除されます。しかし、このメソッドは実際に配列内のオブジェクトを削除していないので、forループでチェックするのは難しいでしょう。私はどこが間違っていたのだろうか?更新 - 動的に行を追加/削除すると、正常に動作しない

更新日: 1.追加jsfiddle https://jsfiddle.net/69z2wepo/84246/ 2.保存ドロップダウン値を親の状態に

constructor(props){ 
    super(props) 
    this.state = { 
    dropdown: [ 
     {first: "true", hideAdd: "false", result: ""} 
    ] 
    } 
    this.addRow = this.addRow.bind(this); 
    this.removeRow = this.removeRow.bind(this); 
    this.onChange = this.onChange.bind(this); 
} 

onChange = (key, value) => { 
    let oldArray = JSON.parse(JSON.stringify(this.state.dropdown)); 
    oldArray[key]['result'] = value; 
    this.setState({dropdown:oldArray}, function(){ 
     console.log(this.state.dropdown); 
     //console.log(this.state.dropdown.length) 
    }) 
} 

removeRow = (e, key) => { 
    e.preventDefault(); 

    let oldArray = JSON.parse(JSON.stringify(this.state.dropdown)); 

    oldArray.slice(); 
    oldArray.splice(key, 1); 

    for (let i=0; i<oldArray.length; i++){ 

     if (i==0){ 
      oldArray[i]['first'] = 'true'; 
     } 

     if (oldArray.length==1){ 
      oldArray[i]['hideAdd'] = 'false'; 
     }else{ 
      oldArray[i]['hideAdd'] = 'true'; 
      if (i == oldArray.length-1){ 
       oldArray[i]['hideAdd'] = 'false'; 
      } 
     } 

    } 

    this.setState({dropdown:oldArray}, function(){ 
     console.log(this.state.dropdown); 
     //console.log(oldArray); 
     //console.log(oldArray.length); 
    }) 

} 
render() { 
     return (
      <Grid.Column> 
       <Grid style={comStyles().gridWidth}> 
        <Grid.Row> 
         <Grid.Column width={4} textAlign='left' style={comStyles().lineHeight}>Then</Grid.Column> 
         <Grid.Column width={12}> 
          { 
          this.state.dropdown.map((item, index) => (
           <RulesThenDropdown default={item.result} onChange={this.onChange} add={this.addRow} remove={this.removeRow} id={index} key={index} hideAdd={item.hideAdd} first={item.first} /> 
          )) 
         } 
         </Grid.Column> 
        </Grid.Row> 
       </Grid> 
      </Grid.Column> 
     ) 
    } 

そして以下が

render() { 
    const Options = thenOptions; 

    let extra = ""; 

    const removeBtn = <button onClick={(e,m)=>this.props.remove(e,this.props.id)} className="circular ui icon button"><i className="icon minus"></i></button> 
    const addBtn = <button onClick={(e,m)=>this.props.add(e,this.props.id)} className="circular ui icon button"><i className="icon plus"></i></button> 

    if(this.props.first==="false"){ 
     if(this.props.hideAdd=="true"){ 
      extra = removeBtn; 
     }else{ 
      extra = <div>{addBtn}{removeBtn}</div>; 
     } 
    }else if(this.props.first==="true"){ 
     if(this.props.hideAdd!="true"){ 
      extra = addBtn; 
     }else{ 
      extra = removeBtn; 
     } 
    } 

    return (
     <div style={comStyles().buttonsMainWrapper}> 
      <Form.Dropdown 
       placeholder='Then' 
       fluid 
       selection 
       options={Options} 
       defaultValue = {this.props.result} 
       onChange={(e,{ value })=>this.props.onChange(this.props.id, value)} 
      /> 
      <div style={comStyles().buttonsGroup}> 
      { 
       extra 
      } 
      </div> 
     </div> 
    ) 
} 
+0

のArrayのための良い代替、問題となっていますこの行は 'oldArray.splice(key、1);'ですか?あなたは 'console.log'を試して、前後に' oldArray'の値をチェックしましたか? –

+0

こんにちはFirice、はい、配列が正しいようです – HUNG

+0

'splice'と' delete'の間の 'oldArray'の結果は同じですか? 'oldArray = oldArray.filter(n => n)'で 'delete'を使って' oldArray'を削除した場合はどうすればいいですか? –

答えて

1

問題があなたにある子コンポーネントからのコードですthis.setState()で不変なコピーを更新するのではなく、コンポーネントの状態を直接変更します。

犯人は、この行である:状態をコピーではなく参照を取得し、今oldArrayとthis.state.dropdownの両方がメモリ内の同じ構造を指しているない

let oldArray = this.state.dropdown; 

oldArrayをスライスしてスプライスして更新すると、状態の変更に関するReactコンポーネントの契約が破棄されます(https://facebook.github.io/react/docs/state-and-lifecycle.html#do-not-modify-state-directly参照)。私は、@Kim Burgaardの答えにそれをさらに追加したい

let oldArray = JSON.parse(JSON.stringify(this.state.dropdown)) 

(詳細はhttps://stackoverflow.com/a/5344074/501217を参照)

+0

残念ながら、動作はまだ同じです:( – HUNG

+0

oldArray.slice()とoldArray.splice()の結果を割り当てる必要もあります。array.pushやarray.popとは異なり、配列には影響しませんあなたは既に古い配列をコピーしているので、slice文をスキップして 'oldArray.splice(...) 'を' oldArray = oldArray.splice(...)'に変更することができます –

+0

私はごめんなさい、私はまだ少し混乱している。let oldArray = JSON.parse(JSON.stringify(this.state。落ちる)); 私は最初にこれを行うと、ここでoldArrayは既に深いコピーができていることを意味し、oldArray.splice(key、1)を実行して、いくつかの値を更新して最終的にsetStateを更新するforループを続けることができますか?私が何かのステップを誤解しているかどうか分かりません。 – HUNG

1

Immutable List:この問題を解決するには

、あなたがそうのような深いクローンthis.state.dropdownする必要があります最後にstate

dropdown: List([{first: "true", hideAdd: "false", id: -1}])

関連する問題