Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.3k views
in Technique[技术] by (71.8m points)

javascript - React-Leaflet TypeError: Cannot read property 'lat' of null

I'm working on a map that asks for permissions for the users location. Than if the location is allowed it finds the users location and then changes the coords of the leaflet map to the coords of the user.But, When compiling the code I get the error

TypeError: Cannot read property 'lat' of null

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
import Constants from "expo-constants";
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";
import { render } from 'react-dom';

import 'leaflet/dist/leaflet.css';



export default class App extends React.Component {
  constructor(){
    super();
    this.state = {
      ready: false,
      where: {lat:null, lng:null},
      error: null
    }
  }

  componentDidMount(){
    let geoOptions = {
      enableHighAccuracy: true,
      timeOut: 20000,
      maximumAge: 60 * 60 * 24
    };
    this.setState({ready:false, error: null });
    navigator.geolocation.getCurrentPosition(this.geoSuccess, this.geoFailure, geoOptions);

  }
  geoSuccess = (position) => {
    console.log(position.coords.latitude);

    this.setState({
      ready:true,
      where: {lat: position.coords.latitude, lng:position.coords.longitude}
    })
  }
  geoFailure = (err) => {
    this.setState({error: err.message});
  }
  
  render() {
    return (
      <MapContainer 
      style={{ height: '100%', width: '100%' }}
      center={[this.state.where.lat, this.state.where.lng]} 
      zoom="30" 
      scrollWheelZoom={true}
      >
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
    
      </MapContainer>
    );
  }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

the <App> component will mount first and then after that componentDidMount() will be called as its name says. The reason you are getting this error is that when <App> will be mounted for the first time the this.state.where will be null.

To avoid this error you can do the following trick:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
import Constants from "expo-constants";
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";
import { render } from 'react-dom';

import 'leaflet/dist/leaflet.css';



export default class App extends React.Component {
    constructor() {
        super();
        this.state = {
            ready: false,
            where: { lat: null, lng: null },
            error: null
        }
    }

    componentDidMount() {
        let geoOptions = {
            enableHighAccuracy: true,
            timeOut: 20000,
            maximumAge: 60 * 60 * 24
        };
        this.setState({ ready: false, error: null });
        navigator.geolocation.getCurrentPosition(this.geoSuccess, this.geoFailure, geoOptions);

    }
    geoSuccess = (position) => {
        console.log(position.coords.latitude);

        this.setState({
            ready: true,
            where: { lat: position.coords.latitude, lng: position.coords.longitude }
        })
    }
    geoFailure = (err) => {
        this.setState({ error: err.message });
    }

    render() {
        return (
            <>
                {( this.state.where != null || this.state.where != undefined) &&
                    <MapContainer
                        style={{ height: '100%', width: '100%' }}
                        center={[ this.state.where?.lat , this.state.where?.lng]}
                        zoom="30"
                        scrollWheelZoom={true}
                    >
                        <TileLayer
                            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                        />

                    </MapContainer>
                }
            </>
        );
    }

}

In the above code the MapContainer will not render until you will get this.state.where in the state.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...