React.js - 使用 api 获取的数据单击按钮时未显示组件

React.js - Component is not appearing on button click with the data fetched by api

我想做的是在单击按钮时从天气 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 获取数据,但没有在搜索栏

下获取包含该数据的天气组件

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

  • 我正在使用模板字符串而不是连接字符串。这是最佳做法。
  • 使用 async/await 和 promises
  • 如果 state 中天气变量的长度大于 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;