React setState 未定义?

Posted

技术标签:

【中文标题】React setState 未定义?【英文标题】:React setState is undefined? 【发布时间】: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; 【参考方案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>
        )
    

【讨论】:

以上是关于React setState 未定义?的主要内容,如果未能解决你的问题,请参考以下文章

React.JS TypeError:无法读取未定义的属性“编号”-(在 setState 内)

React 服务器端渲染 AJAX setState() - 未定义文档

反应:TypeError:无法读取未定义的属性“setState”

ReactJs:获取无法读取未定义错误的属性“setState”[重复]

反应:在构造函数上绑定方法时,在 setState 内实现计时器,状态属性未定义

访问数组的索引返回未定义