2017-08-21 26 views
0

時々、状態の更新の前にほとんどの場合、適切な位置を取得できます。render()はヌル状態を取得します。場所+ mapview - レンダリングする前にComponentWillMountで解決されますか?リアクションネイティブ| Expo

私はasync + wait条件を追加しようとしましたが、役に立たないです。どのように私は場所のデータが州に設定されている地図がレンダリングされていることを確認することができます。

ここにコードがあります。

もう一度、次の場所にnexttick()などを配置して、更新された状態がレンダリングされるようにすることができますか?

import React, { Component } from "react"; 
 
import {Platform,Text,Image,View,StyleSheet,Dimensions} from "react-native"; 
 
import { MapView, Constants, Location, Permissions } from "expo"; 
 

 
const { width, height } = Dimensions.get("window"); 
 

 
const SCREEN_HEIGHT = height; 
 
const SCREEN_WIDTH = width; 
 
const ASPECT_RATIO = width/height; 
 
const LATITUDE_DELTA = 0.0922; 
 
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 
 

 
export default class ComplaintScreen extends Component { 
 
    state = { 
 
    location: null, 
 
    errorMessage: null, 
 
    
 
    positionState: { 
 
     latitude: 0, 
 
     longitude: 0, 
 
     latitudeDelta: 0, 
 
     longitudeDelta: 0 
 
    }, 
 

 
    markerPosition: { 
 
     latitude: 0, 
 
     longitude: 0 
 
    } 
 
    }; 
 

 
    async componentWillMount() { 
 
    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!" 
 
     }); 
 
    } else { 
 
     await this._getLocationAsync(); 
 
    } 
 
    } 
 

 
    _getLocationAsync = async() => { 
 
    let { status } = await Permissions.askAsync(Permissions.LOCATION); 
 
    if (status !== "granted") { 
 
     this.setState({ 
 
     errorMessage: "Permission to access location was denied" 
 
     }); 
 
    } 
 

 
    let location = await Location.getCurrentPositionAsync(
 
     { 
 
     enableHighAccuracy: true, timeout:5000, maxiumumAge: 10000 
 
     }); 
 
    this.setState({ location }); 
 
    var lat = parseFloat(location.coords.latitude); 
 
    var long = parseFloat(location.coords.longitude); 
 

 
    
 
    var region = { 
 
     latitude: lat, 
 
     longitude: long, 
 
     latitudeDelta: LATITUDE_DELTA, 
 
     longitudeDelta: LONGITUDE_DELTA 
 
    }; 
 
    this.setState({ positionState: region }); 
 
    this.setState({ markerPosition: region }); 
 
    }; 
 

 

 
render() { 
 
    return (
 
     console.log(this.state.positionState), 
 
     <View style={Styles.container}> 
 
     <MapView style={Styles.map} initialRegion={this.state.positionState}> 
 
      <MapView.Marker coordinate={this.state.markerPosition}> 
 
      <View style={Styles.radius}> 
 
       <View style={Styles.marker} /> 
 
      </View> 
 
      </MapView.Marker> 
 
     </MapView> 
 
     </View> 
 
    ); 
 
    } 
 
} 
 
const Styles = StyleSheet.create({ 
 
{some styles were here removed to keep the post short} 
 
});

+0

あなたは 'this._getLocationAsync()を呼び出すことができない理由;' componentDidMountに? – Umesh

+0

私はそれについて少し不明ですが、コンポーネントがレンダリングされた後に呼び出されることはありませんか? コンポーネントがレンダリングされた場合、この特定の関数は後で実行され、同じ結果が得られますか? –

+0

'this.setState'の前に' await'を入れてみてください – Umesh

答えて

0

私はCOORDSマップを表示するだけにして、更新されているかどうかをチェック後、活動ローダーを追加するような何かをしました。今のところうまくいく、より良いアプローチがあれば、それを愛するだろう。代替案として

import React, { Component } from "react"; 
 
import { 
 
    Platform, 
 
    Text, 
 
    Image, 
 
    View, 
 
    StyleSheet, 
 
    Dimensions, 
 
    ActivityIndicator, 
 
} from "react-native"; 
 
import { MapView, Constants, Location, Permissions } from "expo"; 
 

 
const { width, height } = Dimensions.get("window"); 
 

 
const SCREEN_HEIGHT = height; 
 
const SCREEN_WIDTH = width; 
 
const ASPECT_RATIO = width/height; 
 
const LATITUDE_DELTA = 0.0922; 
 
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 
 

 
export default class ComplaintScreen extends Component { 
 
    static navigationOptions = { 
 
    title: "New Complaint", 
 
    headerStyle: { 
 
     backgroundColor: "#010245", 
 
     paddingTop: Constants.statusBarHeight, 
 
     height: 60 + Constants.statusBarHeight 
 
    }, 
 
    headerTintColor: "#fff", 
 
    headerRight: (
 
     <Image 
 
     source={require("../assets/img/header/hr.png")} 
 
     style={{ justifyContent: "center", padding: 3, margin: 3 }} 
 
     /> 
 
    ) 
 
    }; 
 

 
    state = { 
 
    location: null, 
 
    errorMessage: null, 
 
    loading: true, 
 
    loadingMap:false, 
 
    positionState: { 
 
     latitude: 0, 
 
     longitude: 0, 
 
     latitudeDelta: 0, 
 
     longitudeDelta: 0 
 
    }, 
 

 
    markerPosition: { 
 
     latitude: 0, 
 
     longitude: 0 
 
    } 
 
    }; 
 
    
 
    async componentWillMount() { 
 
    Location.setApiKey('AIzaSyAHSZHScQK-AslKB8QSIyDfqwGc2adFaUM'); 
 
    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!" 
 
     }); 
 
    } else { 
 
     await this._getLocationAsync(); 
 
    } 
 
    } 
 

 
    _getLocationAsync = async() => { 
 
    let { status } = await Permissions.askAsync(Permissions.LOCATION); 
 
    if (status !== "granted") { 
 
     this.setState({ 
 
     errorMessage: "Permission to access location was denied" 
 
     }); 
 
    } 
 

 
    let location = await Location.getCurrentPositionAsync(
 
     { 
 
     enableHighAccuracy: true, timeout:5000, maxiumumAge: 10000 
 
     }); 
 
    this.setState({ location }); 
 
    var lat = parseFloat(location.coords.latitude); 
 
    var long = parseFloat(location.coords.longitude); 
 

 
    
 
    var region = { 
 
     latitude: lat, 
 
     longitude: long, 
 
     latitudeDelta: LATITUDE_DELTA, 
 
     longitudeDelta: LONGITUDE_DELTA 
 
    }; 
 
     this.setState({ positionState: region }); 
 
     this.setState({ markerPosition: region }); 
 
    }; 
 

 
componentDidUpdate(){ 
 
    if (this.state.positionState.latitude!=='0'){ 
 
    this.state.loadingMap = true; 
 
    this.state.loading = false; 
 
    } 
 
} 
 
render() { 
 
    return (
 
     console.log(this.state.positionState), 
 
     
 
     <View style={Styles.container}> 
 
     {this.state.loadingMap && 
 
     <MapView style={Styles.map} initialRegion={this.state.positionState}> 
 
      <MapView.Marker coordinate={this.state.markerPosition}> 
 
      <View style={Styles.radius}> 
 
       <View style={Styles.marker} /> 
 
      </View> 
 
      </MapView.Marker> 
 
     </MapView> 
 
     } 
 
     {this.state.loading && 
 
      <View style={Styles.loading}> 
 
      <ActivityIndicator size='large' /> 
 
      </View> 
 
     } 
 
     </View> 
 
    ); 
 
    } 
 
} 
 
const Styles = StyleSheet.create({ 
 
    radius: { 
 
    height: 50, 
 
    width: 50, 
 
    borderRadius: 50/2, 
 
    overflow: "hidden", 
 
    backgroundColor: "rgba(0, 122, 255, 0.1)", 
 
    borderWidth: 1, 
 
    borderColor: "rgba(0, 112, 255, 0.3)", 
 
    alignItems: "center", 
 
    justifyContent: "center" 
 
    }, 
 
    marker: { 
 
    height: 20, 
 
    width: 20, 
 
    borderWidth: 3, 
 
    borderColor: "white", 
 
    borderRadius: 20/2, 
 
    overflow: "hidden", 
 
    backgroundColor: "#007AFF" 
 
    }, 
 

 
    container: { 
 
    flex: 1, 
 
    justifyContent: "center", 
 
    alignItems: "center", 
 
    backgroundColor: "#F5FCFF" 
 
    }, 
 

 
    map: { 
 
    left: 0, 
 
    right: 0, 
 
    top: 0, 
 
    bottom: 0, 
 
    position: "absolute" 
 
    }, 
 
    loading: { 
 
    position: 'absolute', 
 
    left: 0, 
 
    right: 0, 
 
    top: 0, 
 
    bottom: 0, 
 
    alignItems: 'center', 
 
    justifyContent: 'center' 
 
    } 
 
});

1

、あなたものMapViewの参照を使用することによって反応するマップネイティブanimateToRegionを呼び出したいことがあります。

これが私のプロジェクトのために働く私の提案の代替です:

_getLocationAsync = async()=> { 
let {status} = await Permissions.askAsync(Permissions.LOCATION); 
if(status!=='granted'){ 
    this.setState({errorMessage:"Permissions not granted."}) 
} 
let location = await Location.getCurrentPositionAsync({}); 
this.map.animateToRegion({ 
    latitude: location.coords.latitude, 
    longitude: location.coords.longitude, 
    latitudeDelta: 0.0922, 
    longitudeDelta: 0.0421, 
}, 200)} 

チェックアウトここで参照: MapView API

関連する問題