【问题标题】:React setState is undefined?React setState 未定义?
【发布时间】:2020-05-08 02:34:26
【问题描述】:

我有这个从浏览器导航器功能到天气 api 的简单获取位置。我不明白为什么纬度和经度的控制台都可以工作,但是当我执行 setState 时,它​​对我大喊大叫说未捕获TypeError: Cannot read property 'setState' of undefined.

为了更清楚这两个控制台,我得到了位置

console.log(position.coords.latitude)
console.log(position.coords.longitude)

但这是说不能将未定义的东西传递给 setState

this.setState({lat:position.coords.latitude,lon:position.coords.longitude})

import React from 'react';
import axios from 'axios';
import WeatherGadget from './weather.component'

export default class WeatherApi extends React.Component {
    constructor(props) {
        super(props);
        this.state = { city: null,lat:0,lon:0,wind:0,weather:0,icon:null };
      }

    componentDidMount() {
       const location = ()=>{navigator.geolocation.getCurrentPosition(function(position) {
           console.log(position.coords.latitude)
           console.log(position.coords.longitude)
            this.setState({lat:position.coords.latitude,lon:position.coords.longitude})          
            //Uncaught TypeError: Cannot read property 'setState' of undefined
      
        })}
        location();


            const url = `https://api.openweathermap.org/data/2.5/onecall?lat=${this.state.lat}&lon=${this.state.lon}&appid=8821HIDDEN4e9d78`;

            const getWeather = async ()=>{
                let res = await axios.get(url)
                const  weatherObj = res.data;
                console.log("===",weatherObj)

                const currentWeather = weatherObj.current.temp
                const windSpeed = weatherObj.current.wind_speed
                const icon = weatherObj.current.weather[0].icon
                this.setState({wind:windSpeed,weather:currentWeather,icon:icon})
            }
            getWeather()

      
    }  

    render() {
        return (

            <div >
            <WeatherGadget city={this.state.city}  wind ={this.state.wind} weather={this.state.weather} icon={this.state.icon}/>
            </div>
        )
    }
}

【问题讨论】:

  • 该代码块中的 this 与组件范围的 this 不同。尝试在 getCurrentPosition 中使用函数并将其绑定到构造函数中。
  • getCurrentPosition(function(position)使用箭头函数或将其绑定到function(position)
  • 像这样:()=&gt;{navigator.geolocation.getCurrentPosition((position) =&gt;{

标签: javascript reactjs react-native react-redux geolocation


【解决方案1】:

在 navigator 对象中非常简单,您无法访问此对象,因为它具有 window 对象的引用因此我在 promise 中使用 navigator 对象,如果 navigator 给了我纬度和经度,那么如果不拒绝,我会解决我的 promise并返回承诺。

ComponentDidMount 中,我使用 await 调用了该函数,因为它返回了我的承诺,然后我有值然后我设置状态

并调用了另一个getWeather函数

import React from "react";
import axios from "axios";
// import WeatherGadget from './weather.component'

export default class WeatherApi extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      city: null,
      lat: 0,
      lon: 0,
      wind: 0,
      weather: 0,
      icon: null
    };
  }


  async componentDidMount() {
    const location = await this.location();
    location && this.setState({ lat: location.lat, lon: location.long });
    location && this.getWeather();
  }
  location = () => {
   //return the promise that contain the navigator object
    return new Promise((resolve, reject) => {
      try {
        navigator.geolocation.getCurrentPosition(position => {
          resolve({
            lat: position.coords.latitude,
            long: position.coords.longitude
          });
        });
      } catch (error) {
        let temp = {
          lat: 24.8607,
          long: 67.0011
        };
        reject(temp);
      }
    });
  };
//calling weather api
  getWeather = async () => {
    const url = `https://api.openweathermap.org/data/2.5/onecall?lat=${
      this.state.lat
    }&lon=${this.state.lon}&appid=8821HIDDEN4e9d78`;
    console.log("url", url);
    try {
      const res = await axios.get(url);
      if (res) {
        console.log("res", res.data)
        const weatherObj = res.data;
        console.log("===", weatherObj);
        const currentWeather = weatherObj.current.temp;
        const windSpeed = weatherObj.current.wind_speed;
        const icon = weatherObj.current.weather[0].icon;
        this.setState({ wind: windSpeed, weather: currentWeather, icon: icon });
      }
    } catch (error) {
      console.log("error", error)
    }
  };
  render() {
    return (
      <div>
        {/* <WeatherGadget city={this.state.city}  wind ={this.state.wind} weather={this.state.weather} icon={this.state.icon}/> */}
        <p> Lat: {this.state.lat}</p>
        <p> Lng: {this.state.lon}</p>
        <p> Weather: {this.state.weather}</p>
        <p>Wind: {this.state.wind}</p>

      </div>
    );
  }
}

【讨论】:

    【解决方案2】:

    我只需要在组件挂载之外创建函数,然后在内部简单地调用它,如下所示

    import React from 'react';
    import axios from 'axios';
    import WeatherGadget from './weather.component'
    
    export default class WeatherApi extends React.Component {
        constructor(props) {
            super(props);
            this.state = { city: null, lat: 0, lon: 0, wind: 0, weather: 0, icon: null };
        }
        location = () => {
            navigator.geolocation.getCurrentPosition((position) => {
                this.setState({ lat: position.coords.latitude, lon: position.coords.longitude })
                //Uncaught TypeError: Cannot read property 'setState' of undefined
    
                const url = `https://api.openweathermap.org/data/2.5/onecall?lat=${this.state.lat}&lon=${this.state.lon}&appid=8821a871fa3513caf66ad2e8ab4e9d78`;
                console.log("====url", url)
    
                const getWeather = async () => {
                    let res = await axios.get(url)
                    const weatherObj = res.data;
                    console.log("===", weatherObj)
    
                    const currentWeather = weatherObj.current.temp
                    const windSpeed = weatherObj.current.wind_speed
                    const icon = weatherObj.current.weather[0].icon
                    this.setState({ wind: windSpeed, weather: currentWeather, icon: icon })
                }
                getWeather()
    
            })
        }
    
         componentDidMount() {
    
             this.location();
        }
    
        render() {
            return (
    
                <div >
                    <WeatherGadget city={this.state.city} wind={this.state.wind} weather={this.state.weather} icon={this.state.icon} />
                </div>
            )
        }
    }

    【讨论】:

      猜你喜欢
      • 2020-04-02
      • 2019-06-13
      • 2019-05-22
      • 2019-04-09
      • 2018-12-05
      • 2016-03-03
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多