2017-06-07 3 views
0

Ok, das Problem ist also ziemlich einfach, aber schwer zu erklären.Das Entfernen von Eingängen führt zu falschen Werten

Ich mache eine InputGenerator-Komponente, die eine Liste von Eingaben generiert.

Jeder generierte Eingang hat einen entsprechenden "remove" -Button daneben. Die zwei Elemente (die Eingabe und die Schaltfläche) sind innerhalb einer Kartenfunktion in ein Div eingepackt. Das div hat eine einzigartige Schlüsselstütze. Es sieht wie folgt aus (dies ist die ganze Komponente jsx ist):

 <div style={[InputGenerator.style.wrapper]}> 
      <div className="container" style={InputGenerator.style.container}> 
       {this.state.inputs.map((input, idx) => { 
        return (
         <div key={idx} style={[ 
          InputGenerator.style.row, 
          InputGenerator.count > 1 && idx > 0 ? InputGenerator.style.input.pushTop : {}, 
         ]}> 
          <InputText 
           id={input.id} 
           name={input.name} 
           placeholder={input.placeholder} 
           style={input.style} 
          /> 
          <Button 
           style={InputGenerator.style.remove} 
           type={Button.TYPES.BASIC} 
           icon="ion-close-round" 
           onClick={this.remove.bind(this, input.id)} 
          /> 
         </div> 
        ); 
       })} 
      </div> 

      <div className="controls" style={InputGenerator.style.controls}> 
       <Button icon="ion-plus" type={Button.TYPES.PRIMARY} title="Add ingredient" onClick={this.add.bind(this)}/> 
      </div> 
     </div> 

Wie Sie sehen können, werden alle Eingaben in der this.state Objekt gehalten werden, und jedes ist eine eindeutige ID angegeben.

Hier sind die sind hinzufügen und Methoden entfernen:

add():

add() { 
    InputGenerator.count++; 

    const newInput = { 
     id: this.id, 
     name: this.props.name, 
     placeholder: this.props.placeholder, 
     style: this.style, 
     value: '', 
    }; 

    const inputs = this.state.inputs; 

    inputs.push(newInput); 

    this.setState({ inputs }); 
} 

remove():

remove(id) { 
    this.setState({ 
     inputs: this.state.inputs.filter(i => i.id !== id), 
    }); 
} 

Das Problem ist:

  • I Generiere drei Eingaben (mit der Schaltfläche Hinzufügen)
  • I stellen Zufallswerte in die Eingänge (zB: 1, 2, 3)
  • I auf die Schaltfläche Entfernen klicken, auf das erste Element entspricht (mit dem Wert 1)
  • Ergebnis: Zwei Eingangs Elemente mit Werten 1 und 2
  • Erwartet: Zwei Eingabefelder mit den Werten 2 und 3
  • Das Problem: Ich schlage vor, dass die Schlüsselstütze auf dem Wrapping div nicht genug ist, um die Eingabewerte zu verfolgen.

Also, ich bin offen für Ideen und Vorschläge, wie Sie vorgehen.

Hier ist eine isolierte Sandbox mit meiner Komponente zu spielen, um und die „Bug“ in Aktion sehen: https://codesandbox.io/s/5985AKxRB

Vielen Dank im Voraus! :)

Antwort

2

Das Problem, mit dem Sie konfrontiert sind, liegt darin, dass Sie den Status nicht richtig behandeln. Sie müssen den Status aktualisieren, wenn Sie den Eingabewert ändern.

handleChange(index,event) { 
    let inputs = this.state.inputs; 
    inputs[index].value = event.target.value; 
    this.setState({inputs:inputs}) 
    } 

DEMO: DEMO

Hier ist der aktualisierte Code:

import React, { Component } from 'react'; 
    import { render } from 'react-dom'; 
    import Hello from './Hello'; 

    const styles = { 
     fontFamily: 'sans-serif', 
     textAlign: 'center', 
    }; 

    const App =() => 
     <div style={styles}> 
     <InputGenerator /> 
     </div>; 

    class InputGenerator extends Component { 
     constructor() { 
     super(); 
     this.state = { 
      inputs: [], 
     }; 
     } 
     componentWillMount() { 
     this.add(); 
     } 
     handleChange(index,event) { 
     let inputs = this.state.inputs; 
     inputs[index].value = event.target.value; 
     this.setState({inputs:inputs}) 
     } 
     add() { 
     InputGenerator.count++; 

     const newInput = { 
      id: this.id, 
      name: this.props.name, 
      placeholder: this.props.placeholder, 
      style: this.style, 
      value: '', 
     }; 

     const inputs = this.state.inputs; 

     inputs.push(newInput); 

     this.setState({ inputs }); 
     } 
     get id() { 
     if (this.props.id) { 
      return `${this.props.id}-${InputGenerator.count}`; 
     } 

     return `InputGeneratorItem-${InputGenerator.count}`; 
     } 
     get style() { 
     return []; 
     } 
     remove(id) { 

     var state = this.state; 
     state.inputs = state.inputs.filter(i => i.id !== id); 
     this.setState({ 
      inputs: state.inputs 
     }); 
     } 
     render() { 
     return (
      <div> 
      <div className="container"> 
       {this.state.inputs.map((input, idx) => { 
       return (
        <div key={idx}> 
        <input 
         id={input.id} 
         name={input.name} 
         value = {input.value} 
         onChange={this.handleChange.bind(this,idx)} 
         placeholder={input.placeholder} 
        /> 
        <button onClick={this.remove.bind(this, input.id)}> 
         Remove 
        </button> 
        </div> 
       ); 
       })} 
      </div> 

      <div className="controls"> 
       <button onClick={this.add.bind(this)}>Add</button> 
      </div> 
      </div> 
     ); 
     } 
    } 

    InputGenerator.count = 0; 

    render(<App />, document.getElementById('root')); 
+1

Danke, Ved, das ist genau die Art und Weise, es zu tun. Danke noch einmal! :) – brslv

+0

Willkommen. !! Freue mich zu helfen. – Ved

Verwandte Themen