2016-09-21 10 views
0

FixReagieren Eingang nicht aktualisiert, wenn Requisiten

Fügen Sie diese Methode zum ersten Mal empfängt, dass das Element gerendert wird, hat es Zugriff auf die props sofort erhalten.

componentDidMount() { 
    if (typeof this.props.options.value !== "undefined") 
    this.setState({value: this.props.options.value}) 
}, 

Ich habe mehrere reagieren Elemente, die fast wie vorgesehen funktionieren. Ich habe eine Ansicht mit einer Liste von Elementen und einer modalen Ansicht, um sie zu bearbeiten. Wenn auf die Schaltfläche zum Bearbeiten eines Elements geklickt wird, wird das Element auf den ausgewählten Zustand gesetzt, und das modale Formular wird angezeigt (das Element wird als Prop übergeben).

Wenn auf ein Element geklickt wird, wird die modale Ansicht korrekt angezeigt, die übergebenen Textwerte werden jedoch nicht angezeigt. die Elemente des vorherigen ausgewählten Elements werden angezeigt (oder leere Felder, wenn es sich um das erste Element handelt, auf das geklickt wurde). Hier ist die Render-Methode der modalen Ansicht:

render() { 
    console.log('rendering') 
    if(!this.props.poi) 
    return null 
    console.log(this.props.poi.name) 
    var poi = this.props.poi 

    var config = { 
    url: `${context.apiUrl}user/pois/${poi.id}`, 
    method: 'PUT', 
    successMessage: 'El Punto de Interés fue actualizado', 
    successHandler: this.successHandler, 
    hideSubmitButton: true, 
    fields: { 
     name: { 
     label: 'Nombre', 
     type: 'text', 
     value: this.props.poi.name 
     }, 
     location: { 
     label: 'Ubicación', 
     type: 'text', 
     display: false, 
     value: this.props.poi.location 
     }, 
     category_id: { 
     label: 'Categoría', 
     type: 'select', 
     options: context.poi_categories.map((cat) => { 
      return {value: cat.id, desc: cat.name} 
     }) 
     } 
    } 
    } 

    return (
    <div> 
     <Row> 
     <Col size="12"> 
      <Panel> 
      <PanelBody> 
       <FormComponent config={config} ref="form"/> 
      </PanelBody> 
      </Panel> 
     </Col> 
     <Col size="12"> 
      <Panel> 
      <PanelHeading heading="Selecciona la ubicación" /> 
      <Map height="400px" ref="map_update_poi" zoom="15"/> 
      </Panel> 
     </Col> 

     </Row> 
    </div> 
) 
} 

Hier ist die Render-Methode des Formularkomponente:

render() { 
    elems = [] 
    count = 0 

    for (var key in this.props.config.fields) { 
    console.log(this.props.config.fields[key]) 
    var _type = this.props.config.fields[key].type 
    var config = { 
     key: count++, 
     options: this.props.config.fields[key], 
     ref: key, 
     refName: key, 
     fullWidth: this.props.config.fullWidth, 
    } 

    switch (_type) { 
     case 'text': 
     elems.push(<InputElement {...config}/>) 
     break 
     case 'select': 
     elems.push(<SelectElement {...config}/>) 
     break 
     case 'multipleSelect': 
     elems.push(<MultipleSelectElement {...config}/>) 
     break 
     case 'button': 
     elems.push(<ButtonElement {...config}/>) 
     break 
     case 'switcher': 
     elems.push(<SwitcherElement {...config}/>) 
     break 
     case 'timePicker': 
     elems.push(<TimePickerElement {...config}/>) 
     break 
     case 'radio': 
     elems.push(<RadioElement {...config}/>) 
     break 
     case 'autocomplete': 
     elems.push(<AutoCompleteInputElement {...config}/>) 
     break 
    } 
    } 
    console.log(elems) 

    return (
    <form action="#" className="form-horizontal"> 
     <div className="form-content"> 
     {elems} 
     {!this.props.config.hideSubmitButton ? <div className="form-buttons"> 
      <div className="row"> 
      <div className="col-md-offset-3 col-md-9"> 
       <button type="submit" onClick={this.handleSave} 
         className="btn btn-blue btn-ripple">Crear</button> 
      </div> 
      </div> 
     </div> : null} 
     </div> 
    </form> 
) 
} 

Und die Render-Methode des Eingangselementes (removed Variablendeklarationen der Kürze halber keine fehlen):

render() { 
    return (
    <div className={formClass} style={style}> 
     <label className="control-label col-md-3">{this.props.options.label}</label> 
     <div className={inputClass}> 
     <div className="inputer"> 
      <div className="input-wrapper"> 
      <input ref={this.props.refName} type="text" className="form-control" onFocus={this.props.onFocus} 
       placeholder={this.props.placeholder} value={this.state.value} onChange={this.handleChange}/> 
      </div> 
      {validationMsg} 
     </div> 
     </div> 
    </div> 
) 
} 

Schließlich möchte ich die Eingabe bin Überprüfung Requisiten hier:

componentWillReceiveProps(nextProps) { 
    console.log('input element', nextProps) 
    if (typeof this.props.options.value !== "undefined") 
    this.setState({value: this.props.options.value}) 
}, 

Ich habe Protokollanweisungen in jedem "Stop" der Kette hinzugefügt. Die modale Ansicht zeigt das Element korrekt an, die Form zeigt die Strings des letzten angeklickten Elements, und die Requisiten des Eingabeelements zeigen auch Informationen über das zuletzt angeklickte Element. Wenn die Eingabe gerendert wird, ist this.state.value jedoch null (der Wert in getInitialState()) oder der Wert des vorherigen Elements. Entsprechend der Reihenfolge der Protokolle werden die Stützen vor dem Rendern empfangen. Während ich verstehe, dass Statusaktualisierungen nicht unmittelbar sind, wenn das Rendern passiert ist, sollte die Zustandsänderung das Rendern erneut auslösen, diesmal mit den korrekten Werten, aber es passiert nicht und ich verstehe nicht warum!

shown 
list index 1 
name Object { label="Nombre", type="text"} 
location Object { label="Ubicación", type="text", display=false} 
category_id Object { label="Categoría", type="select", options=[2]} 
[Object { key="0", ref="name", props={...}, more...}, Object { key="1", ref="location", props={...}, more...}, Object { key="2", ref="category_id", props={...}, more...}] 
input props Object { options={...}, refName="name", fullWidth=undefined} 
render input null 
input props Object { options={...}, refName="location", fullWidth=undefined}componentWillReceiveProps index.js (line 35220) 
render input null 
** At this point the new element is received ** 
** The objects didn't paste completely, but the correct values are 
    there this time. However, there is no output from componentWillReceiveProps ** 
new poi test02 
rendering update form 
update form test02 
name Object { label="Nombre", type="text", value="test02"} 
location Object { label="Ubicación", type="text", display=false, more...} 
category_id Object { label="Categoría", type="select", options=[2]} 
[Object { key="0", ref="name", props={...}, more...}, Object { key="1", ref="location", props={...}, more...}, Object { key="2", ref="category_id", props={...}, more...}] 
2 render input null 
Object { category="Almacen", category_id=1, id=627, more...} 

Edit 2: Jetzt tritt dieses Problem nur auf dem ersten Klick. Passiert, als ich this.props für nextProps per @ Radio-Vorschlag ersetzt.

Antwort

1

In componentWillReceiveProps, stellen Sie den Zustand nextProps.options.value statt this.props.options.value

componentWillReceiveProps(nextProps) { 
    if (typeof nextProps.options.value !== "undefined") 
    this.setState({value: nextProps.options.value}) 
}, 

Wenn es auf dem ersten machen ist, componentWillReceiveProps nicht genannt wird, so dass Sie componentDidMount verwenden können mit this.props, um das gleiche zu erreichen:

componentDidMount() { 
    if (typeof this.props.options.value !== "undefined") 
    this.setState({value: this.props.options.value}) 
} 
+0

Danke, ich habe diesen Fehler nicht gesehen. Das Problem besteht jedoch weiterhin. Der Render wird nicht ausgelöst, nachdem die Requisiten mit dem gewählten Element gesetzt wurden. Ich werde die Frage bearbeiten, um die Konsolenausgabe einzuschließen. – gamda

+0

Ich habe es vorher nicht bemerkt, aber diese Änderung hat das Problem für jeden Klick nach dem ersten behoben. Die erste hat immer noch das Problem – gamda

+0

componentWillReceiveProps wird nicht beim ersten Render aufgerufen.Sie müssten componentWillMount verwenden oder einen Ausgangszustand haben, der standardmäßig funktioniert. –

Verwandte Themen