Ваша ошибка вызвана вашим методом рендеринга:
render() {
let text = 'Waiting..';
if (this.state.errorMessage) {
text = this.state.errorMessage;
} else if (this.state.location) {
text = JSON.stringify(this.state.location);
}
console.log(text)
return (
<MapView
style={{ flex: 1 }}
region={{
latitude: text.coords.latitude,
longitude: text.coords.longitude,
latitudeDelta: 0.1,
longitudeDelta: 0.1,
}}
/>
);
}
Когда this.state.errorMessage
равен нулю, вы не устанавливаете значение для this.state.location
, поэтому ваш MapView
пытается использовать значениевы устанавливаете text
, что не работает, потому что this.state.location
имеет значение null и выдаст ошибку, если вы попытаетесь получить доступ к значениям на нем.
Когда у вас есть местоположение, вы используете JSON.stringify
для преобразования объекта местоположения в строку, но это мешает вам получить доступ к свойствам объекта.
Когда оба значения this.state.errorMessage
и this.state.location
равны нулю, ваш text
является просто строкой, поэтому это приведет к ошибке MapView
, поскольку вы пытаетесь получить доступ к свойствам объекта в строке.
Вы должны сделать что-то вроде этого:
- Установить начальное значение для загруженного в состоянии
- Установить загруженное состояние в
_getLocationAsync
- Проверять местоположение только еслибыло предоставлено разрешение
- Рефакторинг рендеринга, чтобы он обрабатывал загрузку компонента (должен отображаться один из 3 разных выходов, не загружен, загружен, но с ошибкой, загружен, но с расположением)
Вот этот рефактор
export default class Home extends Component {
state = {
location: null,
errorMessage: null,
loaded: false
};
// componentWillMount has been deprecated, use componentDidMount instead
componentDidMount () {
if (Platform.OS === 'android' && !Constants.isDevice) {
this.setState({
errorMessage: 'Oops, this will not work on Sketch in an Android emulator. Try it on your device!',
loaded:true
});
} else {
this._getLocationAsync();
}
}
_getLocationAsync = async () => {
let { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status !== 'granted') {
this.setState({
errorMessage: 'Permission to access location was denied',
loaded: true
});
} else {
// only check the location if it has been granted
// you also may want to wrap this in a try/catch as async functions can throw
let location = await Location.getCurrentPositionAsync({ enableHighAccuracy: true });
this.setState({ location, loaded: true, errorMessage: null });
}
};
render () {
// check to see if we have loaded
if (this.state.loaded) {
// if we have an error message show it
if (this.state.errorMessage) {
return (
<View style={styles.container}>
<Text>{JSON.stringify(this.state.errorMessage)}</Text>
</View>
);
} else if (this.state.location) {
// if we have a location show it
return (
<MapView
style={{ flex: 1 }}
region={{
latitude: this.state.location.coords.latitude,
longitude: this.state.location.coords.longitude,
latitudeDelta: 0.1,
longitudeDelta: 0.1
}}
/>
);
}
} else {
// if we haven't loaded show a waiting placeholder
return (
<View style={styles.container}>
<Text>Waiting...</Text>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1'
},
paragraph: {
margin: 24,
fontSize: 18,
textAlign: 'center'
}
});