javascript - Location + mapview - ComponentWillMount resolves before render does? React Native | Expo -
i can right location, of time before state updates, render() calls fetching nulled states.
i have tried adding async + await conditions no avail. how can make sure map rendered once location data has been set states.
here's code.
so again, may somewhere place nexttick() or ensure updated states used render?
import react, { component } "react"; import {platform,text,image,view,stylesheet,dimensions} "react-native"; import { mapview, constants, location, permissions } "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, not work on sketch in android emulator. try on device!" }); } else { await this._getlocationasync(); } } _getlocationasync = async () => { let { status } = await permissions.askasync(permissions.location); if (status !== "granted") { this.setstate({ errormessage: "permission access location 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 here removed keep post short} });
i did adding activity loader checking if coords have updated, display map. works now, if there's better approach, love it.
import react, { component } "react"; import { platform, text, image, view, stylesheet, dimensions, activityindicator, } "react-native"; import { mapview, constants, location, permissions } "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, not work on sketch in android emulator. try on device!" }); } else { await this._getlocationasync(); } } _getlocationasync = async () => { let { status } = await permissions.askasync(permissions.location); if (status !== "granted") { this.setstate({ errormessage: "permission access location 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' } });
Comments
Post a Comment