【问题标题】:React- Unhandled Rejection (TypeError): Cannot read property 'city' of undefinedReact-未处理的拒绝(TypeError):无法读取未定义的属性“城市”
【发布时间】:2019-08-06 22:58:47
【问题描述】:

我正在尝试遵循 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 中添加构造函数并绑定提交和 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;

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

【问题讨论】:

  • 你可以试试e.target.value.element.city.value。我不知道这个 api 如何返回一个 json,但似乎函数看不到它。如果这不起作用,请尝试e.target.city.value
  • 你需要在你的构造函数中调用超级构造函数 - 将 props 传入你的构造函数并添加 super(props);。必须先完成超级调用,然后才能使用“this”。

标签: javascript reactjs


【解决方案1】:

你好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;

【讨论】:

  • 这与修复我的 api 调用(我忘了把“http://”放在开头)一起工作。感谢您的时间/帮助!
【解决方案2】:
const city = e.target.element.city.value;

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

【讨论】:

    【解决方案3】:

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

    删除element,一切正常:

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

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

    【讨论】:

    • 您好,感谢您的意见。我尝试从该部分删除元素,但出现错误:TypeError: Cannot read property 'getWeather' of undefined new App src/App.js:11 > 11 | this.getWeather = this.getWeather.bind(this);
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 2019-07-19
    • 2019-06-03
    • 2020-04-09
    • 2019-11-13
    • 2021-10-19
    相关资源
    最近更新 更多