2017-03-21 2 views
1

Was mache ich hier falsch? Das folgende Formular funktionierte gut, bis ich mit der Verkabelung begann. Wenn ich den Code spalte oder den Code protokolliere, kann ich sehen, dass die Werte von 'this.state.data.xxx' bei den Aufruf der Ereignismethode geändert werden, aber die Daten werden dann unmittelbar danach aus den Textfeldern geleert und nicht beibehalten. Ich kann nur denken, dass ich irgendwo etwas falsch mache.Reagieren Formular Textfelder sind keine persistenten Daten zwischen Tastenanschlägen

export default class RegistrationForm extends React.Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
      data: {}, 
      employersLookupData: [] 
     }; 

     this.employersDataSource = new LookupRestServiceGateway("/api/lookups/employers/"); 

     this.handleEmailChange = this.handleEmailChange.bind(this); 
     this.handlePasswordChange = this.handlePasswordChange.bind(this); 
     this.handleConfirmPasswordChange = this.handleConfirmPasswordChange.bind(this); 
     this.handleFirstNameChange = this.handleFirstNameChange.bind(this); 
     this.handleLastNameChange = this.handleLastNameChange.bind(this); 
     this.handleEmployerChange = this.handleEmployerChange.bind(this); 
    } 

    handleEmailChange(e) { 
     console.log(this); 
     this.state.data.email = e.target.value; 
    } 

    handlePasswordChange(e) { 
     this.state.data.password = e.target.value; 
    } 

    handleConfirmPasswordChange(e) { 
     this.state.data.confirmPassword = e.target.value; 
    } 

    handleFirstNameChange(e) { 
     this.state.data.firstName = e.target.value; 
    } 

    handleLastNameChange(e) { 
     this.state.data.lastName = e.target.value; 
    } 

    handleEmployerChange(e) { 
     this.state.data.employerID = e.target.value; 
    } 

    loadLookupData() { 
     this.employersDataSource.getListItems({ successCallback: (data) => { 
      this.setState({ employersLookupData: data ? data.items : [] }); 
     }}); 
    } 

    componentDidMount() { 
     this.loadLookupData(); 
    } 

    render() {                 
     return (
      <Form.Wrapper formId = "registration-form" 
          className = "form-horizontal" 
          onSubmit = {this.onSubmit} 
          onSubmitSuccess = {this.onSubmitSuccess}> 
       <h4>Create a new account.</h4> 
       <hr/> 
       <Form.Line name = "Email" 
          label = "Email" 
          type = "email" 
          inputClassName = "col-md-10 col-sm-9" labelClassName = "col-md-2 col-sm-3" 
          value = {this.state.data.email || ""} 
          onChange = {this.handleEmailChange} /> 
       <Form.Line name = "Password" 
          label = "Password" 
          type = "password" 
          inputClassName = "col-md-10 col-sm-9" labelClassName = "col-md-2 col-sm-3" 
          value = {this.state.data.password || ""} 
          onChange = {this.handlePasswordChange} /> 
       <Form.Line name = "ConfirmPassword" 
          label = "Confirm Password" 
          type = "password" 
          inputClassName = "col-md-10 col-sm-9" labelClassName = "col-md-2 col-sm-3" 
          value = {this.state.data.confirmPassword || ""} 
          onChange = {this.handleConfirmPasswordChange} /> 
       <Form.Line name = "FirstName" 
          label = "First Name" 
          inputClassName = "col-md-10 col-sm-9" labelClassName = "col-md-2 col-sm-3" 
          value = {this.state.data.firstName || ""} 
          onChange = {this.handleFirstNameChange} /> 
       <Form.Line name = "LastName" 
          label = "Last Name" 
          inputClassName = "col-md-10 col-sm-9" labelClassName = "col-md-2 col-sm-3" 
          value = {this.state.data.lastName || ""} 
          onChange = {this.handleLastNameChange} /> 
       <Form.DropDownLine name = "EmployerID" 
            label = "Employer" 
            inputClassName = "col-md-10 col-sm-9" labelClassName = "col-md-2 col-sm-3" 
            emptySelection = "Please select an employer&hellip;" 
            onChange = {this.handleEmployerChange} 
            items = {this.state.data.employersLookupData}/>          
       <Form.Buttons.Wrapper className="col-sm-offset-3 col-md-offset-2 col-md-10 col-sm-9"> 
        <Form.Buttons.Submit text = "Register" 
             icon = "fa-user-plus" /> 
       </Form.Buttons.Wrapper>  
      </Form.Wrapper>                             
     ); 
    } 
} 

Nur der Vollständigkeit halber bezieht sich Form.Line auf die Formline Komponente unter ...

export default class FormLine extends React.Component { 

    render() { 
     let controlClassName = this.props.children 
      ? `form-control ${this.props.controlClassName} noted-form-control` 
      : `form-control ${this.props.controlClassName}`; 

     return (
      <div className="row padded-row"> 
       <div className="form-group"> 
        <FormLabel name = {this.props.name} 
           className = {this.props.labelClassName} 
           value = {this.props.label} /> 
        <div className={this.props.inputClassName}> 
         <TextBox name = {this.props.name} 
           className = {controlClassName} 
           maxLength = {this.props.maxLength} 
           value = {this.props.value} 
           type = {this.props.type} 
           onChange = {this.props.onChange} /> 
         <FormInputNotes>{this.props.children}</FormInputNotes> 
        </div> 
       </div> 
      </div> 
     ); 
    } 
} 

und TextBox wie folgt aussieht ...

export default function TextBox({name = "", value = "", type = "text", className = "", maxLength = 10000, onChange}) { 
    return (
     <input type = {type} 
       htmlFor = {name} 
       className = {`form-control ${className}`} 
       maxLength = {maxLength} 
       value = {value} 
       onChange = {onChange} /> 
    ); 
} 

Antwort

2

Ich denke, Ihr Problem ist, dass Sie die Art und Weise falsch verstehen, wie der Staat verändert werden sollte. Sie tun dies:

this.state.data.employerID = e.target.value; 

und Sie sollten dies tun:

let newData = { 
    ...this.state.data, 
    employerID: e.target.value 
} 
this.setState({data: newData}); 

Nehmen wir ein Beispiel:

Lassen Sie ein Anfangszustand wie folgt beginnen:

this.state = { someValue: 0 }; 

Doing this.state.someValue = 1 benachrichtigt nicht zu reagieren, dass der Status geändert wurde, so wird es nie die canges rendern. Hier findet this.setState statt, wobei es dem React Core meldet, dass sich der Status geändert hat und neu berechnet werden muss (und auch danach gerendert werden muss). Die richtige Art und Weise mit dem Beispiel folgend:

this.setState({ someValue: 0 }); 

In Ihrem Fall durch Sie ein komplexes Objekt verwenden, können Sie das gesamte Objekt ersetzen müssen, das ist, warum Sie eine Kopie machen müssen, ändern Sie den Wert Sie benötigen und aktualisieren Sie es mit this.setState.

Ihre Handler sollte mehr oder weniger wie folgt aussehen:

handleFirstNameChange(e) { 
    //Create a copy of the original object 
    let newData = { 
    ...this.state.data, 
    //Set the new value 
    employerID: e.target.value 
    } 
    //Set the new value through setState 
    this.setState({data: newData}); 
} 

als Referenz oder weitere Informationen über Komponenten des React the full docs lesen. Wenn Sie Zeit haben, werfen Sie einen Blick auf Components Cycle Life.

Lassen Sie mich wissen, ob es funktioniert.

+0

Das ist eine sehr klare Beschreibung, wie es funktionieren soll. Dies ist das erste Mal, dass ich ein flaches Formular wie dieses gemacht habe, da meine vorherigen React-Formulare alle Statusobjekte verwendet haben, die in der Ebene über dem tatsächlichen Formular gehalten werden. Um die Sache zu vereinfachen, habe ich den Status verflacht, so dass die Handler einzelne Werte aktualisieren - das enthaltene Objekt ist unnötig, –

+0

Großartig, aber denken Sie daran, IMMER 'this.setState' zu ​​verwenden. Ich bin froh, dass ich helfen kann! –

Verwandte Themen