我正在尝试使用react-native更新地图上标记的坐标。我正在使用具有一些坐标集的数据。我希望坐标更新。这样我就能看到标记在移动。我在componentDidMount()中应用了setInterval。我能够使用state,props和setInterval移动标记,但是当我尝试更新setInterval中的observable时使用mobx,我收到错误。代码如下。
Map.js
import React from "react";
import MapRender from "./MapRender";
import TestData from "./TestData";
import { observable } from "mobx";
import { Provider, observer } from "mobx-react";
export default class Map extends React.Component {
constructor(props) {
super(props);
console.log("TestData.length = ", TestData.response.result.length);
this.data = TestData.response.result;
}
@observable markers = [{
"_id": "marker",
"latitude": "26.884815",
"longitude": "75.7792617",
"imei": "987654"
}];
componentDidMount() {
let i = 0;
this.interval = setInterval(() => {
this.markers[0].latitude = TestData.response.result[i].latitude;
this.markers[0].longitude = TestData.response.result[i].longitude;
i++;
if(i === 100) i = 0;
}, 1000);
}
componentWillUnMount() {
clearInterval(this.interval);
}
render() {
return (
<Provider markers={this.markers}>
<MapRender polylineArray={this.data} />
</Provider>
);
}
}
MapRender.native.js
import React from "react";
import MapView, { Marker, Polyline } from "react-native-maps";
import Box from "../../../grid-styled/src/Box";
import { observable } from "mobx";
import { inject, observer } from "mobx-react";
const DEFAULT_PADDING = { top: 40, right: 40, bottom: 40, left: 40 };
const width = 300;
const height = 300;
const ASPECT_RATIO = width / height;
const LATITUDE_DELTA = 0.0522;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
@inject("markers")
@inject("manIcon")
@observer
class MapRender extends React.Component {
constructor(props) {
super(props);
this.state = {
region: {
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}
};
this.drawPolyline = this.drawPolyline.bind(this);
this.addOrUpdateMarker = this.addOrUpdateMarker.bind(this);
this.addOrUpdateMarkers = this.addOrUpdateMarkers.bind(this);
}
drawPolyline(polylineArray) {
let polylineArrayFloat = [];
polylineArrayFloat = polylineArray.map(elem => {
let returnValue = {};
returnValue.id = elem.id;
returnValue.latitude = parseFloat(elem.latitude);
returnValue.longitude = parseFloat(elem.longitude);
return returnValue;
});
return (
<MapView.Polyline
key="polyline"
coordinates={polylineArrayFloat}
strokeColor={"blue"}
fillColor={"rgba(255,0,0,0.5)"}
strokeWidth={2}
/>
);
}
addOrUpdateMarkers(markers) {
markers.map(marker => this.addOrUpdateMarker(marker));
}
addOrUpdateMarker(marker) {
let { markers } = this.props;
var found = markers.find(mark => mark.id == marker.id);
if (found) {
found.latitude = marker.latitude;
found.longitude = marker.longitude;
} else markers.push(marker);
}
drawMarker(marker, i) {
return (
<MapView.Marker
identifier={marker.id}
coordinate={{
latitude: parseFloat(marker.latitude),
longitude: parseFloat(marker.longitude)
}}
key={"__marker" + i}
/>
);
}
drawMarkers(markers) {
this.addOrUpdateMarkers(markers);
let returnValue = [];
markers.map((marker, i) => {
returnValue[i] = this.drawMarker(marker, i);
if(!React.isValidElement(returnValue[i])) throw Error("Not Valid Element");
});
return returnValue;
}
render() {
let { polylineArray, markers } = this.props;
console.warn(JSON.stringify(markers));
return (
<Box h={height} bg="red" w={width}>
<MapView
ref={ref => (this.map = ref)}
style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0 }}
initialRegion={{
latitude: parseFloat(this.props.polylineArray[0].latitude),
longitude: parseFloat(this.props.polylineArray[0].longitude),
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LATITUDE_DELTA
}}
>
{this.drawMarkers(markers)}
{this.drawPolyline(polylineArray)}
</MapView>
</Box>
);
}
}
export default MapRender;
TestData.js
module.exports = {
"response": {
"result": [{
"_id": "5a31c6b9e9fd1265f115bd21",
"latitude": "26.884815",
"longitude": "75.7792617",
"imei": "987654"
}, {
"_id": "5a31ccafe9fd1265f1164beb",
"latitude": "26.8854983",
"longitude": "75.7822483",
"imei": "987654"
}, {
"_id": "5a31ccb3e9fd1265f1164c93",
"latitude": "26.8856533",
"longitude": "75.7823383",
"imei": "987654"
}, {
"_id": "5a31ccbae9fd1265f1164d68",
"latitude": "26.885835",
"longitude": "75.7824267",
"imei": "987654"
}, {
"_id": "5a31ccbee9fd1265f1164e09",
"latitude": "26.8859617",
"longitude": "75.7824983",
"imei": "987654"
}]
}
}
这是我得到的错误
Error: [mobx] Invariant failed: Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, the render function of a React component? Tried to modify: Map@11.markers[..].latitude
This error is located at:
in MapRender (created by inject-MapRender-with-markers)
in inject-MapRender-with-markers (at Map.js:51)
in Provider (at Map.js:50)
in Map (at UserRoutes.js:23)
in Provider (at RouterFP.js:242)
in RCTView (at View.js:113)
in View (at StackView.js:44)
in Provider (at StackView.js:38)
in StackView (at Nav.js:113)
in RCTView (at View.js:113)
in View (at StyledBox.native.js:14)
in Box (created by Styled(Box))
in Styled(Box) (at Box.js:34)
in Container (at Nav.js:112)
in RCTView (at View.js:113)
in View (at StyledBox.native.js:14)
in Box (created by Styled(Box))
in Styled(Box) (at Box.js:34)
in Container (at BgBox.native.js:14)
in BgBox (at Nav.js:110)
in Provider (at Nav.js:109)
in Nav (created by inject-Nav-with-backgroundImage)
in inject-Nav-with-backgroundImage (created by inject-inject-Nav-with-backgroundImage-with-navBodyStyle)
in inject-inject-Nav-with-backgroundImage-with-navBodyStyle (at ManazeAppFP.js:46)
in Router (created by inject-Router-with-params)
in inject-Router-with-params (created by inject-inject-Router-with-params-with-path)
答案 0 :(得分:1)
在<MapRender />
组件中,您从addOrUpdateMarker
调用render
函数,此函数正在更改您的mobx状态。
在这种情况下,mobx警告你这是错误的,因为它可能会在渲染功能中产生副作用。