开发者问题收集

React:未捕获的类型错误:无法读取未定义的属性(读取‘setState’)

2022-08-27
565

我是 React 的新手,我想通过 API 调用来获取一些东西,但这似乎对我来说不起作用。对于以下代码,我在标题中提到的控制台中收到错误。

错误显示在以下代码的 fetch 语句中,我无法纠正它。我在这里做的是获取位置的纬度和经度并将其传递给 URL 以获取天气。

从“react”导入 React,{ Component }

class WeatherData extends Component{
  constructor(props){
    super(props);
    this.state ={
      weatherReport:[]
    };
  }

  componentDidMount() {
    navigator.geolocation.getCurrentPosition(function(position) {
      const lat =  position.coords.latitude;
      const lon = position.coords.longitude;
    fetch('https://api.openweathermap.org/data/2.5/weather?lat='+{lat}+'&lon='+{lon}+'&appid=xxxxxxxxxxxxxxxxxxxxxxx')
    .then(response => response.json())
    .then(data => this.setState({ weatherReport: data.main}));
    });
    
}
  render(){
    const  { weatherReport }  = this.state;

    
    return(
      <div>
          {weatherReport.temp}
      </div>
    );
  }
}

export default WeatherData;

任何帮助都将不胜感激。

2个回答

这是由于使用 function 关键字和“粗箭头”语法 ( => ) 之间的差异造成的。

function 关键字创建了一个新的“ this 上下文”,而粗箭头则继承了父上下文。 换句话说,当您使用 function 时, this 关键字的值在该函数内部变为新值,而使用 => 时,它与函数外部的值保持不变。

您可以在此处阅读有关 this 关键字的更多信息:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

有关 function=> 之间差异的更多信息,请参见此处:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions


因此,不要这样写:
getCurrentPosition(function(position) {

你应该这样写:
getCurrentPosition((position) => {

完整示例:

import React, { Component } from "react"

class WeatherData extends Component {
  constructor(props) {
    super(props);
    this.state = {
      weatherReport: []
    };
  }

  componentDidMount() {
    navigator.geolocation.getCurrentPosition((position) => { // <- this is what has changed
      const lat = position.coords.latitude;
      const lon = position.coords.longitude;
      fetch('https://api.openweathermap.org/data/2.5/weather?lat=' + { lat } + '&lon=' + { lon } + '&appid=xxxxxxxxxxxxxxxxxxxxxxx')
        .then(response => response.json())
        .then(data => this.setState({ weatherReport: data.main }));
    });
  }

  render() {
    const { weatherReport } = this.state;

    return (
      <div>
        {weatherReport.temp}
      </div>
    );
  }
}

export default WeatherData;
Justin Taddei
2022-08-27

获取地理位置时,您使用的是使用 function 关键字的函数 - 这会为其范围内的任何内容(包括箭头函数及其内容)提供新的 this 引用。使用胖箭头函数将当前 this 绑定到其子块,以便在使用回调时保持正确的范围。

此外,不确定您为什么要像这样在 URL 中链接对象:

componentDidMount() {
    navigator.geolocation.getCurrentPosition((position) => { // this line
        const lat = position.coords.latitude;
        const lon = position.coords.longitude;
        fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=xxxxxxxxxxxxxxxxxxxxxxx`
          .then(response => response.json())
          .then(data => this.setState({
            weatherReport: data.main
          }));
        });
    }
casraf
2022-08-27