在Android上强制退出并重新打开应用后,组件上的引用为null

时间:2019-05-16 16:49:03

标签: reactjs react-native

我为使用react-native-maps的React Native应用提供了此代码。我试图通过在Marker组件上创建引用,使用Marker组件的showCallout方法,使Marker的Callout组件在应用启动时立即打开。这是代码:

some_list = "Select person, age, name, sum(count distinct arrests) from...".split(' ')
matching = [s for s in some_list if "(" in s][0]
print(matching) # sum(count


some_list = "COUNT(DISTINCT(case when etc...)".split(' ')
matching = [s for s in some_list if "(" in s][0]
print(matching) # COUNT(DISTINCT(case

该代码可在首次打开应用程序时按预期工作。但是,当我强制退出应用程序并尝试重新打开它时,出现此错误:

import React, { Component } from "react";
import { Platform, StyleSheet, Text, View } from "react-native";
import MapView, { PROVIDER_GOOGLE, Marker, Callout } from "react-native-maps";
import { PermissionsAndroid } from "react-native";
import { apiKey } from "./apiKey";
import CustomCallout from "./CustomCallout";

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      latitude: null,
      longitude: null,
      error: null,
      locationGranted: null,
      currentWeather: "Loading weather data..."
    };
    this.requestLocationPermission = this.requestLocationPermission.bind(this);
    this.getWeather = this.getWeather.bind(this);
    this.setMarkerRefresh = this.setMarkerRefresh.bind(this);
  }

  componentDidMount() {
    this.requestLocationPermission();
  }

  async getWeather(lat, long) {
    try {
      let response = await fetch(
        `https://api.darksky.net/forecast/${apiKey}/${lat},${long}`
      );
      let responseJson = await response.json();
      let thisHour = responseJson.hourly.data[0];
      this.setState(
        {
          currentWeather: `${thisHour.temperature} ${thisHour.windSpeed} ${
            thisHour.summary
          }`
        },
        this.setMarkerRefresh
      );
    } catch (error) {
      console.error(error);
    }
  }

  setMarkerRefresh() {
    setTimeout(this.currentMarker.showCallout, 1);
  }

  async requestLocationPermission() {
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        {
          title: "Location Permission",
          message:
            "This app needs access to your location to provide you location data.",
          buttonPositive: "OK"
        }
      );
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        navigator.geolocation.getCurrentPosition(
          position => {
            this.setState({
              latitude: position.coords.latitude,
              longitude: position.coords.longitude,
              error: null,
              locationGranted: true
            });
            this.getWeather(
              position.coords.latitude,
              position.coords.longitude
            );
          },
          error => this.setState({ error: error.message }),
          { enableHighAccuracy: true, timeout: 200000, maximumAge: 1000 }
        );
      } else {
        this.setState({ locationGranted: false });
      }
    } catch (err) {
      console.warn(err);
    }
  }

  render() {
    if (this.state.locationGranted === false) {
      return (
        <View>
          <Text> Please enable location to use this app. </Text>
        </View>
      );
    } else if (this.state.latitude === null || this.state.longitude === null) {
      return (
        <View>
          <Text> {this.state.error} </Text>
        </View>
      );
    } else {
      return (
        <View style={styles.container}>
          <MapView
            provider={PROVIDER_GOOGLE} // remove if not using Google Maps
            style={styles.map}
            region={{
              latitude: this.state.latitude,
              longitude: this.state.longitude,
              latitudeDelta: 0.025,
              longitudeDelta: 0.025
            }}
          >
            <Marker
              coordinate={{
                latitude: this.state.latitude,
                longitude: this.state.longitude
              }}
              ref={ref => {
                this.currentMarker = ref;
              }}
            >
              <Callout tooltip={true}>
                <CustomCallout>
                  <Text style={{ color: "white", textAlign: "center" }}>
                    {this.state.currentWeather}
                  </Text>
                </CustomCallout>
              </Callout>
            </Marker>
          </MapView>
        </View>
      );
    }
  }
}

const styles = StyleSheet.create({
  container: {
    ...StyleSheet.absoluteFill,
    justifyContent: "flex-end",
    alignItems: "center"
  },
  map: {
    ...StyleSheet.absoluteFillObject
  },
  customView: {
    width: 140,
    height: 140
  }
});

我不太确定导致此错误的组件安装/卸载方面发生了什么。我曾尝试过在线搜索,但没有取得太大的成功。有人可以帮我吗?谢谢!

1 个答案:

答案 0 :(得分:0)

您可以将方法setMarkerRefresh更改为

setMarkerRefresh() {
    // setTimeout(this.currentMarker.showCallout, 1);
    setTimeout(() => {
      this.currentMarker.showCallout;
    }, 1000);
  }