Sie haben versucht, den Schlüssel auf ein Objekt, das gemeint ist, unveränderlich und eingefroren wurde
Im folgenden Beispiel:
MapView
zeigt Elemente einerListView
als Anmerkungen- Klicken auf eine
ListView
element sollte das Ergebnis in der Malerei es in blau Farbe. - Bonus, wenn der
MapView
undListView
eine effiziente Nutzung der staatlichen Objekt
Änderung der DataSource
von ListView
scheint zu bewirken, dass der Konflikt, wenn die active
Attribut wird geändert:
Du versucht, den key 'active' mit dem Wert 'false' auf eine
Objekt, das gemeint ist, unveränderlich und fixiert wurde.
Was ist die richtige Methode zum festlegen der Staat?
'use strict';
import React, {Component} from 'react';
import {AppRegistry,View,ListView,MapView,Text,TouchableOpacity} from 'react-native';
var annotations = [
{
title: 'A',active: false,latitude: 45,longitude: 26,latitudeDelta: 0.015,longitudeDelta: 0.015,
},{
title: 'B',active: false,latitude: 49,longitude: 14,latitudeDelta: 0.015,longitudeDelta: 0.015,
},{
title: 'C',active: false,latitude: 26,longitude: 25,latitudeDelta: 0.015,longitudeDelta: 0.015,
}
]
class SampleApp extends Component {
constructor(props) {
super(props);
var ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
});
this.state = {
region: annotations[0],
annotations: annotations,
dataSource: ds.cloneWithRows(annotations)
};
}
handleClick(field) {
if (this.previousField) {
this.previousField.active = false;
}
this.previousField = field;
field.active = true;
this.setState({
region: field,
});
}
renderField(field) {
let color = (field.active == true)?'blue':'yellow';
return (
<TouchableOpacity onPress={this.handleClick.bind(this,field)}>
<Text style={{backgroundColor:color,borderWidth:1}}>{field.title}</Text>
</TouchableOpacity>
);
}
render() {
return (
<View style={{flex:1,flexDirection:'column',alignSelf:'stretch'}}>
<MapView
style={{flex:0.5,alignSelf:'stretch',borderWidth:1}}
region={this.state.region}
annotations={this.state.annotations}
/>
<ListView
dataSource={this.state.dataSource}
renderRow={(field) => this.renderField(field)}
/>
</View>
);
}
}
AppRegistry.registerComponent('SampleApp', () => SampleApp);
InformationsquelleAutor Peter Gerhat | 2016-07-08
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das Problem
Wenn Sie
field.active = true;
oderthis.previousField.active = false;
, die Sie Bearbeiten, ein Objekt (field
), die in der Datenquelle desListView
. DieListView
den Fehler auslöst, weil es friert der datasource-wenn Sie es schaffen, mitcloneWithRows
. Dies ist, um sicherzustellen, dass die datasource kann nicht geändert werden, die außerhalb der normalen Reagieren Komponente Lebenszyklus (wiesetState
). StattdessenListView.DataSource
Objekte sind entworfen, um sich mitcloneWithRows
gibt eine kopieren der vorhandenen datasource.Wenn Sie vertraut sind mit der Redux library, es ist sehr ähnlich wie die Philosophie mit reducer-Funktionen geben einen kopieren des Staates, eher als Modifikation des bestehenden Staates.
Klonen Sie die DataSource -
Um dieses problem zu lösen, anstatt mutiert
field
Objekte in IhremhandleClick
Funktion, was Sie wirklich wollen, zu tun ist, erstellen Sie eine neue Daten-array mit Werten, die bereits (wieactive
), und rufen Sie dannsetState
mit einer neuen Datenquelle für denListView
erstellt mitcloneWithRows
. Wenn Sie dies tun, die Sie eigentlich gar nicht brauchen, dieannotations
Schlüssel in Ihrem Zustand überhaupt.Code ist wahrscheinlich hilfreicher als Worte hier:
Ich hoffe, das hilft! Hier ist ein code-snippet mit dem vollständigen code, den Sie geschrieben, mit meinen änderungen. Es funktioniert für mich nur, wie du es beschrieben hast, sollte auf iOS verwenden, Reagieren die Einheimischen auf 0,29. Sie hat die Frage nach android-mapview, also bin ich davon ausgegangen, dass Sie mit Android, aber die Plattform sollte nicht wirklich einen Unterschied machen in diesem Fall.
JS: