2017-05-17 3 views
1

Also das Problem, das ich gerade habe, ist auf den ersten Klick, meine GUI re-rendert. Aber beim zweiten Klick wird das Rendering nicht durchgeführt. Ich glaube, es liegt daran, dass ich den Zustand von "graphicLayers" nicht aktualisiere, den mein Render durch die "graphicLayers.map" bindet. Das ist meine Theorie sowieso (auch wenn es funktioniert auf dem ersten klicken? Aber nicht den zweiten Klick oder etwas nach)Kann ich einen rerender mit setState erzwingen, auch wenn sich die Daten nicht geändert haben? Meine GUI wird nicht aktualisiert

Ich habe versucht, eine setState Update von graphicLayers zwingen, aber es scheint nicht zu funktionieren .. wie diese

let graphicLayersCopy = Object.assign([], this.state.graphicLayers); 
this.setState({graphicLayers: graphicLayersCopy}); 

aber das funktioniert nicht. Ich weiß durch den Debugger, dass es die Daten richtig einstellt, und wenn ich aktualisiere (es speichert Zustand und lädt den Zustand neu), dann wird die GUI richtig gerendert.

Gibt es trotzdem ich kann ein Rendern einer Variablen erzwingen, wie auch wenn es Wert nicht ändert?

Konstruktor

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

    this.state = { 
     graphicLayers: [id1, id2, id3], 
     graphicLayersById: { 
     id1: { ... }, 
     id2: { ... }, 
     id3: { ... } 
     } 

    this.addLayerClick = this.addLayerClick.bind(this); 
}; 

machen

render() { 
    return (  
    <div> 
     {this.state.graphicLayers.map((id) => 
     <GraphicLayer addLayerClick={this.addLayerClick.bind(this)} /> 
    )} 
    </div> 
    ); 
    } 

addLayerClick

addLayerClick() { 
    ... change some property in graphicLayersById dictionary ... 
    self.setState({ graphicLayersById: newDataHere }); 
} 

EDIT: Hey Leute, so fand ich das Problem auf meinem Ende, und es ist nicht genau ist hier gezeigt.

Also meine AddLayerClick() ruft tatsächlich eine andere Funktionen, die auf einen Anruf zu hören ist und es setzt den Zustand in. es ist komisch, weil der setState in der Callback-Funktion aufgerufen wird, aber ich habe es zum Funktionieren gebracht, indem ich den setState in addLayerClick() selbst gesetzt habe .. weiß immer noch nicht, warum das nicht funktioniert, aber ich werde euch alle mindestens aufladen

listenFunction() {

let self = this; 

this.firebaseWrapper.storage.on('graphicLayersById', function (save) { 
    if (save) { 
    self.setState({ graphicLayersById: save }); // FOR SOME REASON THIS DOESN'T UPDATE THE GUI THE 2nd CLICK. The data is correct though and I see it going here on a breakpoint, but GUI won't update unless i setState in the actual button 
    } 
    else { 
    self.setState({ graphicLayersById: undefined }); 
    } 
}); 

}

+0

.bind (this) wird zweimal geschrieben. –

+0

@TreefishZhang hey danke für den Kommentar. Ich habe das tatsächlich hinzugefügt, als ich das Problem in der Hoffnung fand, dass es funktionieren würde. Ich entfernte es zwar nur basierend auf Ihrem Kommentar und ließ den im Konstruktor, aber immer noch das gleiche Problem leider – user1189352

+0

Ich habe window.location.reload() verwendet Erzwingen rerender, aber es ist teuer: ganze Seite wird neu gestrichen. –

Antwort

2

Eigentlich haben, können Sie die addLayerClick() Funktion an die Komponente gebunden ist, so können Sie this statt self

verwenden, sollten Sie revidieren Sie den Code wie folgt aus: (es gibt etwa 2 Änderungen)

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

    this.state = { 
     graphicLayers: [id1, id2, id3], 
     graphicLayersById: { 
     id1: { ... }, 
     id2: { ... }, 
     id3: { ... } 
     } 
    // don't need to bind here anymore, since you bind it in the click 
    //this.addLayerClick = this.addLayerClick.bind(this); 
}; 

addLayerClick() { 
    //... change some property in graphicLayersById dictionary ... 
    // just use 'this' here 
    this.setState({ graphicLayersById: newDataHere }); 

    // the below line is NOT recommended, which is force the component to update 
    // this.forceUpdate(); // this line will update the component even though there's no change 
} 

Wenn dies noch nicht funktioniert, bitte hier posten, wie Sie onCLick Funktion in der Unterkomponente verarbeiten und veröffentlichen auch einige Fehler, wenn überhaupt, dank

+0

danke, versuchen Sie dies und melden Sie sich bei – user1189352

2

hoffen, dass diese zwei mögliche Weg, um Ihre Ansicht

this.setState({graphicLayersById: newDataHere} ,()=>{ 
console.log(this.state.graphicLayersById); 
}); 

ODER

var update = require('react-addons-update'); 
    var graphicLayers = update(this.state, { 
      graphicLayersById: {$set: newDataHere} 
     }); 
     this.setState(graphicLayers); 
+0

Vielen Dank, Sie werden es versuchen! – user1189352

2
Reder wird

In addLayerClick() aktualisieren Sie nur graphicLayersById, aber das Rendern hängt von graphicLayers ab. Sie sollten auch den graphicLayers-Status in aktualisieren.

addLayerClick() { 
    this.setState({ 
    graphicLayers: ... 
    graphicLayersById: .... 
    }); 
} 

Auf einer Seite beachten, sollten Sie nicht binden Methoden innerhalb render() da, dass eine neue Funktion Marke schafft auf jeden machen (und könnte Auswirkungen auf die Leistung). Statt

<GraphicLayer addLayerClick={this.addLayerClick.bind(this)} /> 

tun

<GraphicLayer addLayerClick={this.addLayerClick} /> 

und die Bindung in Ihrem Konstruktor verlassen (die Art und Weise haben Sie bereits).

Verwandte Themen