React-未处理的拒绝(TypeError):无法读取未定义的属性“ city”

时间:2019-03-15 19:50:22

标签: javascript reactjs

我正在尝试在youtube上跟随一个教程,该教程使用openweathermap api基于用户的两次输入来显示位置的天气,但出现此错误:

Unhandled Rejection (TypeError): Cannot read property 'city' of undefined
_callee$
src/App.js:16
  13 | 
  14 | getWeather = async e => {
  15 |   e.preventDefault();
> 16 |   const city = e.target.element.city.value;
     | ^  17 |   const country = e.target.element.country.value;
  18 |   const api_call = await fetch(
  19 |     `api.openweathermap.org/data/2.5/weather?q=${city},${country}&APPID=${API_KEY}`

关于类似问题,这里有很多帖子,人们建议在App.js中添加一个构造函数,并绑定Submit和getWeather函数。我一直在尝试,它给了我一个不同的错误:

TypeError: Cannot read property 'getWeather' of undefined
new App
src/App.js:10
   7 | 
   8 | class App extends React.Component {
   9 |   constructor() {
> 10 |     this.getWeather = this.getWeather.bind(this);
  11 |     this.onSubmit = this.onSubmit.bind(this);
  12 |   }
  13 | 

我的代码当前如下所示-App.js:

import React from "react";
import Titles from "./components/Titles.js";
import Form from "./components/Form.js";
import Weather from "./components/Weather.js";

const API_KEY = "ca4d2addb51bf577deda4bf791f7f683";
class App extends React.Component {
  constructor() {
    this.getWeather = this.getWeather.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }
  getWeather = async e => {
    e.preventDefault();
    const city = e.target.element.city.value;
    const country = e.target.element.country.value;
    const api_call = //makes api call
    const data = await api_call.json();
    console.log(data);
  };
  render() {
    return (
      <div>
        <Titles />
        <Form getWeather={this.getWeather} />
        <Weather />
      </div>
    );
  }
}
export default App;

Form.js:

import React from "react";

class Form extends React.Component {
  render() {
    return (
      <form onSubmit={this.props.getWeather}>
        <input type="text" name="city" placeholder="City..." />
        <input type="text" name="country" placeholder="Country..." />
        <button>Get Weather</button>
      </form>
    );
  }
}
export default Form;

有什么想法吗?谢谢您的宝贵时间。

3 个答案:

答案 0 :(得分:0)

const city = e.target.element.city.value;

您将必须检查响应是否不为空。 所以像这样 if (e && e.target && e.target.element && e.target.city && e.target.city.value)

答案 1 :(得分:0)

错误是说e.target中没有属性element

删除element,一切正常:

const city = e.target.city.value;
const country = e.target.country.value;

示例:https://codesandbox.io/s/pkmy81k5nj

答案 2 :(得分:0)

您好,rollerpigeon,请参阅代码以了解您遇到的所有错误...请务必阅读每条注释。

import React from 'react'

import Form from "./Form.js";

import './App.css'

class App extends React.Component {
  constructor() {
    super() // error # 0, just required
    // this.getWeather = this.getWeather.bind(this); // don't need this if use function declaration option # 2, but it is always needed for option # 1
    // this.onSubmit = this.onSubmit.bind(this); // error # 1 - onSubmit not defined in the class

    this.state = {
      result: 'empty result'
    }
  }

  // async getWeather(e) { // declaration option # 1
  getWeather = async e => { // declaration option # 2
    e.preventDefault();
    const city = e.target.city.value; // error # 3 - previously e.target."element".city.value -- element ? what is that?
    const country = e.target.country.value; // error # 4 - previously e.target.element. -- element ?
    const api_call = await apiCall(city, country)
    const data = await api_call.json();

    this.setState({
      result: data
    })
  };

  render() {
    return ( <
      div >
      Hello <
      Form getWeather = {
        this.getWeather
      }
      /> <
      div > {
        this.state.result
      } <
      /div> <
      /div>
    );
  }
}

function apiCall(city, country) {
  return {
    json: () => new Promise((resolve) => {
      const r = JSON.stringify({
        city,
        country
      }, null, 2)
      setTimeout(() => resolve(`Result for : ${r}`), 1500)
    })
  }
}


export default App;