2016-06-27 4 views
3

Ich habe ein Formular erstellt, wo es ein Dropdown-Feld gibt, auf dem die Auswahl unter den Feldern angezeigt wird. Also sagen wir, zuerst wurde optionSet1 ausgewählt, für das 3 Felder angezeigt werden sollen. Wenn der Benutzer das Dropdown-Menü zur Auswahl von optionSet2 ändert, werden verschiedene Optionen angezeigt.reactjs componentWillUnmount wird nicht aufgerufen

Aber wenn optionSet2 wird gerendert und optionSet1 entfernt wird, sollte componentWillUnmount für die einzelnen InputFields zuvor gemacht genannt haben, was nicht der Fall ist. Diese Funktion wird nie aufgerufen.

class LeadUpdate extends React.Component { 
    constructor(props, context) { 
    super(props, context); 
    } 

    _getUpdateFields() { 
    let fields = this.props.inputFields[this.state.updateType]; 

    return _.map(fields, f => { 
     _.assignIn(f, { 
     fieldParentClass: 'form-group col-lg-6', 
     eventName: this.state.eventName 
     }); 
     return <InputField config={f} /> 
    }); 
    } 

    _onChange(id, value) { 
    this.setState({ 
     optionSet: value 
    }); 
    } 

    render() { 
    return (<div> 
     <div className="col-lg-5"> 
     <form role="form" className="vymo-form"> 
      <InputField values={this.props.values} onChange={this._onChange.bind(this)} /> 
     </form> 
     </div> 

     <div className="row"> 
     <form role="form" className="vymo-form"> 
      {this._getUpdateFields()} 
     </form> 
     </div> 
    </div>) 
    } 
} 

Update: Ich habe gerade festgestellt, dass componentWillUnmount genannt wird, aber das eigentliche Problem ist mit eventListner. Ich gebe hier Codes ein.

Problem - Ich verwende nodejs Ereignisse zum Abrufen von Werten aus verschiedenen Eingabefeldern gefüllt. Wenn jedoch OptionSet geändert wird, werden alle zuvor nicht eingebundenen Optionen ebenfalls auf das Ereignis gelauscht.

Inputfield -

import eventsService from '../../../services/events-service'; 

class InputField extends React.Component { 

    constructor(props, context) { 
     super(props, context); 

     this.state = { 
      id: this.props.id, 
      value: this._getInputFieldValue() || '', 
      valid: true, 
      errorVisible: false, 
      errorMessage: '' 
     }; 
    } 

    componentWillMount() { 
     if(this.props.eventName) { 
      this._subscription = eventsService.emitter.addListener(this.props.eventName, this._validate.bind(this)); 
     } 
    } 

    componentWillUnmount() { 
     if(this.props.eventName) { 
      eventsService.emitter.removeListener(this.props.eventName, this._validate.bind(this)); 
     } 
    } 

    _handleChange(event) { 

     if(this.props.onChange) { 
      this.props.onChange.call(null, this.state.id, event.target.value); 
     } 
     this.setState({ 
      value: event.target.value 
     }); 
    } 

    _getClasses(classes) { 
     if (classes) { 
      return classes.join(' '); 
     } 
    } 

    _getInputFieldProps() { 
     let inputProps = { 
      value: this.state.value, 
      type: this.props.type, 
      placeholder: this.props.placeholder || '', 
      id: this.props.id, 
      onChange: this._handleChange.bind(this), 
      className: this._getClasses(this.props.classes) ? this._getClasses(this.props.classes) + 'form-control' : 'form-control', 
      maxlength: this.props.maxLength, 
      disabled: this.props.disabled ? "true" : null, 
      min: this.props.min, 
      max: this.props.max, 
      readOnly: this.props.readonly ? "true" : null, 
      required: this.props.required 
     }; 

     return inputProps; 
    } 

    _validate(result) { 
     if (this.props.required && !this.state.value) { 
      valid = false; 
      this.setState({ 
       errorVisible: true, 
       errorMessage: 'this is required field', 
       valid: false 
      }); 
     } 


     if(valid) { 
      this.setState({ 
       errorVisible: false, 
       errorMessage: 'this is not a valid phone number', 
       valid: true 
      }); 
     } 

     result.valid &= valid; 
     result.values.push({ 
      type: this.props.type, 
      code: this.state.id, 
      value: this.state.value, 
      name: this.props.label 
     }); 


    } 

    _getInputFieldValue() { 
     switch (this.props.type) { 
      case Types.NUMBER: 
      case Types.EMAIL: 
      case Types.DECIMAL: 
      case Types.PHONE: 
      case Types.TEXT: 
       return this.props.value; 
     } 
    } 

    render() { 
     let props = this._getInputFieldProps(); 
     return (<div className={this.props.fieldParentClass}> 
      <label for={this.props.id}><span>{this.props.label}</span><span>{props.required ? '*' : ''}</span></label> 
      <input {...props}/> 
      <span className={this.state.errorVisible ? 'show' : 'hide'}>{this.state.errorMessage}</span> 
     </div>) 
    } 

} 

Event-Service: -

import {EventEmitter} from 'events'; 
//TODO make this as constant 
var emmiter = new EventEmitter(); 
export default { 
    emitter: emmiter, 

} 

Ich verstehe das Event-Service ist schlecht, es ist einfach war schnell diese Funktionalität zu testen.

+1

Können Sie bitte weitere Informationen teilen? Ich sehe 'componentWillUnmount' hier nicht und auch render() gibt keine korrekte Syntax zurück. Vielen Dank. – Grgur

+0

ja, entfernte unnötige Codes. um es einfach zu machen. Wrapped es in div so jetzt wird es gültiges HTML zurückgeben. @Grgur – user2696466

+0

Ich habe Ihre Code-Formatierung korrigiert, aber zuerst habe ich auch eine 'return' zu Ihrer' render'-Methode hinzugefügt, aber ich habe sie wieder entfernt, falls die fehlende 'return' für Ihre Probleme relevant war. – demux

Antwort

1

Ich fand es heraus. Beim "Unrendering" von Komponenten über den Status müssen sie ein Schlüsselattribut haben.

{this.state.mode === 'custom' ? 
    <Field 
     label="A" 
     name="requested_completes" 
     type="number" 
     key="a" 
    /> 
    : 
    <Field 
     label="B" 
     name="requested_completes" 
     type="dropdown" 
     key="b" 
    /> 
}