ReactJS 对对象数组使用 setState()
ReactJS Using setState() for an array of objects
我在使用 setStates 时遇到问题。我在我的状态下为我的 Google 地图存储了一个标记数组,我正在使用 for 循环遍历每个标记,以便使用 Google 的地理编码 API.
这是我的状态:
state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {},
markers: [
{
name: "Costco Wholesale",
address: "9151 Bridgeport Rd, Richmond, BC V6X 3L9",
position: { lat: 0, lng: 0 },
placeID: 'ChIJWc2NzuF0hlQRDu0NNhdQCjM'
} //just trying to get this one to work first before I add in the others
],
busy: []
};
这是函数(在 class 中声明):
findLatLong(){
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.state.markers[i].position.setState({lat: lati, lng: lngi})
}
);
}
}
如您所见,我将同一数组元素中包含的地址传递给 .fromAddress 函数,然后使用 setState 将 lat 和 lng 设置为返回值。
我后来在地图渲染之后但在标记渲染之前调用了该函数:
<Map
google={this.props.google}
zoom={14}
style={mapStyles}
initialCenter={{ lat: 49.166590, lng: -123.133569 }}
>
{this.findLatLong}
{this.state.markers.map((marker, index) => (
<Marker
key={index}
onClick={this.onMarkerClick}
name={marker.name}
position={marker.position}
/>
))}
但是标记的位置状态没有改变,而是保留为我在初始状态声明期间传递的填充值。
如果有帮助,请提供完整代码:
import React, { Component } from 'react';
import { Map, GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';
import Geocode from 'react-geocode';
const key = '';
Geocode.setApiKey(key);
const mapStyles = {
width: '100%',
height: '100%'
};
export class MapContainer extends Component {
state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {},
markers: [
{
name: "Costco Wholesale",
address: "9151 Bridgeport Rd, Richmond, BC V6X 3L9",
position: { lat: 0, lng: 0 },
placeID: 'ChIJWc2NzuF0hlQRDu0NNhdQCjM'
}
],
busy: []
};
findLatLong(){
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.state.markers[i].position.setState({lat: lati, lng: lngi})
}
);
}
}
componentDidMount() {
this.getList();
}
getList = () => {
fetch('/api/getList')
.then(res => res.json())
.then(percent => this.setState({ busy: percent }))
}
onMarkerClick = (props, marker, e) =>
this.setState({
selectedPlace: props,
activeMarker: marker,
showingInfoWindow: true
});
onClose = props => {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
};
render() {
return (
<Map
google={this.props.google}
zoom={14}
style={mapStyles}
initialCenter={{ lat: 49.166590, lng: -123.133569 }}
>
{this.findLatLong}
{this.state.markers.map((marker, index) => (
<Marker
key={index}
onClick={this.onMarkerClick}
name={marker.name}
position={marker.position}
/>
))}
<InfoWindow
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
onClose={this.onClose}
>
<div>
<h4>{this.state.selectedPlace.name}</h4>
<h4>{this.state.busy}</h4>
</div>
</InfoWindow>
</Map>
);
}
}
提前致谢!
尝试修复 #1
.then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.setState(oldState => {
const newMarkers = [oldState.markers];
const modifiedMarker = newMarkers[i];
modifiedMarker.lat = lati;
modifiedMarker.lng = lngi;
return {oldState, markers: [newMarkers]};
//How do i implement the modifiedMarkers?
})
更新
实际上,如果只改变一次状态而不是在循环内改变状态会更好
findLatLong(){
const newMarkers = [...this.state.markers]
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
newMarkers[i].position.lat = lati;
newMarkers[i].position.lng = lngi;
}
);
}
this.setState(oldState => {
return { ...oldState, markers: [...newMakers] };
});
}
这不是改变状态的方式,它应该是这样的:
this.setState(oldState => {
const newMakers = [...oldState.makers];
const modifiedElement = newMakers[i];
modifiedElement.lat = lati;
modifiedElement.lng = lngi;
return { ...oldState, makers: [...newMakers] };
});
我在使用 setStates 时遇到问题。我在我的状态下为我的 Google 地图存储了一个标记数组,我正在使用 for 循环遍历每个标记,以便使用 Google 的地理编码 API.
这是我的状态:
state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {},
markers: [
{
name: "Costco Wholesale",
address: "9151 Bridgeport Rd, Richmond, BC V6X 3L9",
position: { lat: 0, lng: 0 },
placeID: 'ChIJWc2NzuF0hlQRDu0NNhdQCjM'
} //just trying to get this one to work first before I add in the others
],
busy: []
};
这是函数(在 class 中声明):
findLatLong(){
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.state.markers[i].position.setState({lat: lati, lng: lngi})
}
);
}
}
如您所见,我将同一数组元素中包含的地址传递给 .fromAddress 函数,然后使用 setState 将 lat 和 lng 设置为返回值。
我后来在地图渲染之后但在标记渲染之前调用了该函数:
<Map
google={this.props.google}
zoom={14}
style={mapStyles}
initialCenter={{ lat: 49.166590, lng: -123.133569 }}
>
{this.findLatLong}
{this.state.markers.map((marker, index) => (
<Marker
key={index}
onClick={this.onMarkerClick}
name={marker.name}
position={marker.position}
/>
))}
但是标记的位置状态没有改变,而是保留为我在初始状态声明期间传递的填充值。
如果有帮助,请提供完整代码:
import React, { Component } from 'react';
import { Map, GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';
import Geocode from 'react-geocode';
const key = '';
Geocode.setApiKey(key);
const mapStyles = {
width: '100%',
height: '100%'
};
export class MapContainer extends Component {
state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {},
markers: [
{
name: "Costco Wholesale",
address: "9151 Bridgeport Rd, Richmond, BC V6X 3L9",
position: { lat: 0, lng: 0 },
placeID: 'ChIJWc2NzuF0hlQRDu0NNhdQCjM'
}
],
busy: []
};
findLatLong(){
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.state.markers[i].position.setState({lat: lati, lng: lngi})
}
);
}
}
componentDidMount() {
this.getList();
}
getList = () => {
fetch('/api/getList')
.then(res => res.json())
.then(percent => this.setState({ busy: percent }))
}
onMarkerClick = (props, marker, e) =>
this.setState({
selectedPlace: props,
activeMarker: marker,
showingInfoWindow: true
});
onClose = props => {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
};
render() {
return (
<Map
google={this.props.google}
zoom={14}
style={mapStyles}
initialCenter={{ lat: 49.166590, lng: -123.133569 }}
>
{this.findLatLong}
{this.state.markers.map((marker, index) => (
<Marker
key={index}
onClick={this.onMarkerClick}
name={marker.name}
position={marker.position}
/>
))}
<InfoWindow
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
onClose={this.onClose}
>
<div>
<h4>{this.state.selectedPlace.name}</h4>
<h4>{this.state.busy}</h4>
</div>
</InfoWindow>
</Map>
);
}
}
提前致谢!
尝试修复 #1
.then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.setState(oldState => {
const newMarkers = [oldState.markers];
const modifiedMarker = newMarkers[i];
modifiedMarker.lat = lati;
modifiedMarker.lng = lngi;
return {oldState, markers: [newMarkers]};
//How do i implement the modifiedMarkers?
})
更新
实际上,如果只改变一次状态而不是在循环内改变状态会更好
findLatLong(){
const newMarkers = [...this.state.markers]
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
newMarkers[i].position.lat = lati;
newMarkers[i].position.lng = lngi;
}
);
}
this.setState(oldState => {
return { ...oldState, markers: [...newMakers] };
});
}
这不是改变状态的方式,它应该是这样的:
this.setState(oldState => {
const newMakers = [...oldState.makers];
const modifiedElement = newMakers[i];
modifiedElement.lat = lati;
modifiedElement.lng = lngi;
return { ...oldState, makers: [...newMakers] };
});