【问题标题】:React JS - render data from Open AQ APIReact JS - 从 Open AQ API 渲染数据
【发布时间】:2020-04-08 03:12:39
【问题描述】:

我正在尝试使用来自Open AQ 的数据制作显示所选国家/地区污染最严重的 10 个城市的应用程序。但是,我收到错误消息,上面写着TypeError: this.props.cities.map is not a function,我不知道应该如何解决它。我发布了整个代码,因为您可能会发现一些我什至没有考虑过的错误。

这是我的应用文件:

import React from 'react';
import './App.css';
import Input from './components/Input';
import CitiesList from './components/CitiesList';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: '',
      cities: []
    };
    this.onCountryChange = this.onCountryChange.bind(this);
    this.airQuality = this.airQuality.bind(this);
  }

  onCountryChange = (event) => {
    this.setState({
      countryCode: event.target.value
    })
  };

  airQuality = () => {
    const URL = 'https://api.openaq.org/v1/measurements?country=${countryCode}&limit=10&order_by=value&sort=desc';

    fetch(URL) 
      .then(response => {
        if (response.ok) {
          return response;
        }
        throw Error(response.status)
      })
      .then(response => response.json())
      .then(data => {
        this.setState({
          cities: data.results
        })
      })
      .catch(error => console.log(error))
  }



  render() {
    return (
      <div>
        <Input onChange={this.onCountryChange}/>
        <CitiesList cities={this.airQuality}/>
      </div>
    )
  }
}

export default App;

输入文件:

import React from 'react';
import TextField from '@material-ui/core/TextField';
import Autocomplete from '@material-ui/lab/Autocomplete';

const countries = [
    {country: 'Poland', value: 'PL'},
    {country: 'Germany', value: 'DE'},
    {country: 'Spain', value: 'ES'},
    {country: 'France', value: 'FR'}
]

class Input extends React.Component {

    render() {
        return (
            <Autocomplete
            id="combo-box"
            options={countries}
            getOptionLabel={option => option.country}
            style={{ width: 300, marginTop: 10 }}
            renderInput={params => (
              <TextField {...params} label="Type a country" variant="outlined" fullWidth />
            )}
          />
        )
    }
}

export default Input;

CitiesList 我得到错误的地方:

import React from 'react';

class CitiesList extends React.Component {

    render() {
        const items = this.props.cities.map((city, i) => (
            <div key={i}>
                <h2>{city.name}</h2>
                <p>
                    <div>
                        Parameter: {city.parameter}
                    </div>
                    <div>
                        Value: {city.value} {city.unit}
                    </div>
                </p>
            </div>
        ));
        return (
            <div>
                {items}
            </div>
        )
    }
}


export default CitiesList;

感谢您的帮助。


编辑: Akshit Mehra 和 Roman Unt 帮助了我很多,我解决了我的代码中的两个问题,但是仍然存在一些错误。当我选择国家并看到时,它仍然不显示城市,这是因为countryCode 没有更新。函数onCountryChange 甚至没有触发,我意识到这是因为 onChange 事件处理程序应该在输入标签中,我把它放在名为 Input 的组件中。所以我把它移到了Autocomplete 组件,现在我有了:

App.js

<Input onCountryChange={this.onCountryChange}/>

Input.js

const Input = ({onCountryChange}) => (
    <Autocomplete
    id="combo-box"
    options={countries}
    getOptionLabel={option => option.country}
    style={{ width: 300, marginTop: 10 }}
    onChange={onCountryChange}
    renderInput={params => (
      <TextField {...params} label="Type a country" variant="outlined" fullWidth />
    )}
    />
)

现在我在控制台中看到函数 onCountryChange 触发,但它仍然没有更新 countryCode(this.state.countryCode 为 0)。

你能帮忙吗?

【问题讨论】:

  • 你为什么在这里通过获取方法?而不是通过获取的城市传递状态?

标签: reactjs api dictionary fetch typeerror


【解决方案1】:

您将 airQuality 传递给您的 &lt;CitiesList cities={this.airQuality} /&gt; 组件,这是一个方法而不是可迭代数组。此方法正在更新cities 状态,您应该在cities 数组上使用.map() 函数。

相反,将cities 状态传递为props,例如&lt;CitiesList cities={this.state.cities} /&gt;

如果这有帮助,请告诉我。

【讨论】:

  • 谢谢,它有帮助,现在我没有错误了。但是它仍然不起作用,我的意思是,当我选择国家时,它不显示城市。也许我理解不正确,但我认为我应该以某种方式将 airQuality 放在渲染方法中(但是如何?),因为现在看起来应用程序不使用这种方法。
  • 您可以根据需要在componentDidMount() 和/或componentDidUpdate() 生命周期挂钩中调用this.airQuality() 方法。所有从 API 获取数据的调用都应通过这些生命周期挂钩进行。
  • 谢谢,帮了大忙,但还是有问题。我把它写成问题的编辑。
【解决方案2】:

我做了几次更正,现在它呈现数据。

  1. 我更改了onCountryChange 函数。现在我在 Input.js 中:
const countries = [
    {country: 'Poland', code: 'PL'},
    {country: 'Germany', code: 'DE'},
    {country: 'Spain', code: 'ES'},
    {country: 'France', code: 'FR'}
]

在 App.js 中:

onCountryChange = (object, value) => {
    this.setState({
      countryCode: value.code
    });

  };

在渲染方法中:

const { countryCode } = this.state;
  1. const URL 中,我将引号更改为反引号,将countryCode 更改为this.state.countryCode

  2. 我把componentDidMount改成了componentDidUpdate

我仍然需要改进它,因为我在控制台中看到,airQuality 函数不断循环,并且在渲染 10 个元素后它不会停止,而且它不显示城市名称,而只显示参数,价值和单位,但我更进一步:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多