为了账号安全,请及时绑定邮箱和手机立即绑定

如何在设置之前停止将状态元素传递给子组件?

如何在设置之前停止将状态元素传递给子组件?

隔江千里 2023-03-10 15:16:45
我正在用 React 编写一个天气预报应用程序。我正在从 openweathermap.org API 获取数据。但是要使用它,我需要知道用户的位置。所以我也依次使用其他 API 来识别用户 IP、位置,然后根据该位置识别天气数据。在每个获取状态,我都会用获取的信息更新初始状态。例如,当我获取 Ip 时,我使用 setState 更新状态中的 userIP,然后当获取纬度和经度时,我也更新 userLat 和 userLng。因此,states 中的 weatherData 最初是一个空数组,是最后一个被更新的。问题是,每次更改其中一个状态时都会运行渲染。由于我将 weatherData 作为道具传递给的子组件之一使用了该获取的 weatherData 数组中的对象,我得到一个错误,因为在更新 weatherData 之前,渲染运行并将一个空数组传递给该组件。我尝试使用 if 语句在返回结果之前检查 weatherData 是否为空数组,但不知何故它不起作用。这是我的 App.js 文件:import React, {Component} from 'react';import './App.css';import Mainblock from './Mainblock';import Hourly from './Hourly';import Weekly from './Weekly';class App extends Component {  constructor() {    super()    this.state = {      userIp: 0,      cityName: '',      cityNameNoSpace: '',      userLat: 0,      userLng: 0    }  }    componentDidMount(){    fetch("https://geoip-db.com/json/").then((data)=> {      return data.json();    }).then((ip)=>{      this.setState({userIp: ip.IPv4});      this.locateClient(this.state.userIp);    });  }  locateClient = (clientIp) => {    fetch(`https://ip-geolocation.whoisxmlapi.com/api/v1?apiKey=at_SECRETAPIKEY&ipAddress=${clientIp}`).then((data)=>{      return data.json();    }).then((locationInfo)=>{      this.setState({userLat: locationInfo.location.lat, userLng: locationInfo.location.lng, cityName: locationInfo.location.city});      let cityArray = Array.from(locationInfo.location.city);      let cityNameFiltered = '';            cityArray.forEach((letter)=>{        cityNameFiltered = cityNameFiltered + letter;        return cityNameFiltered;      })      this.setState({cityNameNoSpace: cityNameFiltered});      this.getWeatherData(this.state.cityNameNoSpace);    });  }  getWeatherData = (userCity) => {    fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${this.state.userLat}&lon=${this.state.userLng}&units=metric&appid=SECRETAPIKEY`).then((data)=>{      return data.json();    }).then((weatherInfo)=>{      this.setState({weatherData: weatherInfo});    });  }
查看完整描述

1 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

由于您的Mainblock组件期望 states 属性是一个具有属性 weatherData 的对象,其中 weatherData 应该是一个数组,因此您可以有条件地渲染组件。


有条件地渲染它看起来像下面这样:


render() {

    return (

      <div className="whole-container">

        <div className="lside">

          {Array.isArray(this.state.weatherData) && <Mainblock states={this.state}/> }

          <Weekly />

        </div> 

        <Hourly />

      </div>

    );

  }

这样做的原因是 javascript 计算布尔表达式并在 true 时返回表达式的右侧,否则返回 false。


> true && 123

< 123

> false && 123

< false


查看完整回答
反对 回复 2023-03-10
  • 1 回答
  • 0 关注
  • 63 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信