【问题标题】:React.js - Component is not appearing on button click with the data fetched by apiReact.js - 组件未出现在按钮单击时,api 获取的数据
【发布时间】:2020-08-07 23:00:13
【问题描述】:

我要做的是在按钮单击时从 Weather API 获取数据,当获取数据时,该数据应映射到组件(即天气)内,然后仅该组件应出现在屏幕,现在我可以获取数据,但即使这样组件也没有出现。

Container.jsx

import React from 'react';
import './container.css'
import Weather from './weather';
class Container extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            location: "",
            weather: []
        };
    }
    handleChange = (e) => {
        this.setState({ [e.target.name]: e.target.value });
    };

    componentDidMount() {
    }

    continue = (e) => {

        const { location } = this.state;
        const rawurl = 'http://api.weatherstack.com/current?access_key=d8fefab56305f5a343b0eab4f837fec1&query=' + location;
        const url = rawurl;
        //e.preventDefault();
        if (location.length < 1) {
            return alert('Enter the details');
        }
        else {
                fetch(url)
                    .then(response => response.json())
                    .then(data =>{
                        this.setState({weather:data});
                    })
                    .catch(err => console.log("error ",err)) 
        }
    };
    render() {
        console.log(this.state);
        const weather =
        this.state.weather.length> 0 ? 
        this.state.weather.map(item => (<Weather location={item.location.name} temperature={item.current.temperature} weather={item.current.weather_descriptions[0]} windSpeed={item.current.wind_speed} windDegree={item.current.wind_degree} windDir={item.current.wind_dir} humidity={item.current.humidity} visibility={item.current.visibility} />
            ))
        :<span></span>
        return (
            <div id="container">
                <div class="searchicon">
                    <input type="search" placeholder="Enter City !!" type="text" name="location" value={this.state.location} onChange={this.handleChange}></input>
                    <label class="icon">
                        <button onClick={this.continue}><span class="fa fa-search"></span></button>
                    </label>
                </div>
                <div>
                {weather}
                </div>
                
            </div>
        );
    }
}
export default Container;

Weather.jsx

import React from 'react';

class Weather extends React.Component {
    render(){
        return (
            <div id="result">
                <div id="location" class="insideres">
                    <div class="title">
                        Location
                    </div>
                    <div class="res">
                        {this.props.location}
                    </div>
                </div>
                <div id="Temperature" class="insideres">
                    <div class="title">
                        Temperature
                    </div>
                    <div class="res">
                    {this.props.temperature}
                    </div>
                </div>
                <div id="Weather" class="insideres">
                    <div class="title">
                        Weather
                    </div>
                    <div class="res">
                    {this.props.weather}
                    </div>
                </div>
                <div id="Windspeed" class="insideres">
                    <div class="title">
                        Wind Speed
                    </div>
                    <div class="res">
                    {this.props.windSpeed}
                    </div>
                </div>
                <div id="Wind_degree" class="insideres">
                    <div class="title">
                        Wind Degree
                    </div>
                    <div class="res">
                    {this.props.windDegree}
                    </div>
                </div>
                <div id="Wind_dir" class="insideres">
                    <div class="title">
                        Wind Direction
                    </div>
                    <div class="res">
                    {this.props.windDir}
                    </div>
                </div>
                <div id="Humidity" class="insideres">
                    <div class="title">
                        Humidity
                    </div>
                    <div class="res">
                    {this.props.humidity}
                    </div>
                </div>
                <div id="Visibility" class="insideres">
                    <div class="title">
                        Visibility
                    </div>
                    <div class="res">
                    {this.props.visibility}
                    </div>
                </div>
            </div>
        );    
    }
}
export default Weather;

我希望在从 api 获取数据时显示此天气组件,但现在正在获取数据但未显示。

在上图中,您可以看到我正在从 api 获取数据,但没有在搜索栏下获取带有该数据的 Weather 组件

【问题讨论】:

  • 可能天气对象不是数组,也许你应该记录你从API收到的数据,找到你想要的天气数据,也许你应该做的是this.setState({weather:data 。数据}); ,但先记录你收到的数据,然后找到你想要的部分
  • 它是一个数组,我正在获取有关获取的数据,但获取的数据未显示组件 Weather。
  • 从截图中可以看出,天气不是数组,能否请您显示您记录的天气对象
  • @AliAbuHijleh 天气是数组,我已经打印了整个状态
  • 我看到它是一个对象不是数组,重新检查一下

标签: reactjs api fetch react-component


【解决方案1】:

这里是使用带有钩子的 react 对组件的更新。我强烈建议您采用这种模式,因为它更容易使用,但如果您尚未采用这种模式,则需要使用 React 16。你会注意到我:

  • 我正在使用模板字符串而不是连接字符串。这是最佳做法。
  • 将 async/await 与 Promise 一起使用
  • 如果状态中的天气变量的长度大于0,则使用if语句渲染天气组件。如果不是,它将渲染容器组件。
import "./container.css";

import React, { useState } from "react";

import Weather from "./weather";

const Container = () => {
    const [location, setLocation] = useState("");
    const [weather, setWeather] = useState([]);

    const fetchWeatherData = async () => {
        const url = `http://api.weatherstack.com/current?access_key=d8fefab56305f5a343b0eab4f837fec1&query=${location}`;
        if (location.length < 1) {
            return alert("Enter the details");
        } else {
            await fetch(url)
                .then((response) => response.json())
                .then((data) => {
                    setWeather(data);
                })
                .catch((err) => console.log("error ", err));
        }
    };

    if (weather.length > 0) {
        return weather.map((item) => (
            <Weather
                location={item.location.name}
                temperature={item.current.temperature}
                weather={item.current.weather_descriptions[0]}
                windSpeed={item.current.wind_speed}
                windDegree={item.current.wind_degree}
                windDir={item.current.wind_dir}
                humidity={item.current.humidity}
                visibility={item.current.visibility}
            />
        ));
    }

    return (
        <div id="container">
            <div className="searchicon">
                <input
                    placeholder="Enter City !!"
                    type="text"
                    name="location"
                    value={location}
                    onChange={(e) => setLocation(e.target.value)}
                />
                <label className="icon">
                    <button onClick={fetchWeatherData}>
                        <span className="fa fa-search" />
                    </button>
                </label>
            </div>
            <div>{weather}</div>
        </div>
    );
};

export default Container;

【讨论】:

  • 收到此错误 -> 错误:对象作为 React 子项无效(找到:带有键 {request, location, current} 的对象)。如果您打算渲染一组子项,请改用数组。在 div (at container.jsx:56) 在 div (at container.jsx:41) 在 Container (at App.js:11) 在 div (at App.js:9) 在 App (at src/index.js: 9) 在 StrictMode (在 src/index.js:8)
  • 这可能是容器末尾的 div,其中包含 {weather}。我建议删除它或将天气数组映射到组件中。请记住按照它在错误中为您提供的错误中的行进行调试。
猜你喜欢
  • 1970-01-01
  • 2017-10-12
  • 2017-10-07
  • 1970-01-01
  • 2020-05-15
  • 2017-07-01
  • 1970-01-01
  • 2023-03-23
  • 2021-02-15
相关资源
最近更新 更多