javascript - 使用 Ajax 在 React 中打开天气数据

标签 javascript jquery json ajax reactjs

鉴于Open Weather Map current weather data API ,我尝试使用 ajax 将当前天气数据提取到我的 React.js 应用程序中,提取给定城市的当前温度值,然后在我的组件中渲染该值。

我正在使用的测试 JSON 数据位于以下网址: http://api.openweathermap.org/data/2.5/weather?id=5391997&units=imperial

var CityGrid = React.createClass({
  componentDidMount: function() {
    $.ajax({
      url: 'http://api.openweathermap.org/data/2.5/weather?id=5391997', 
      // ^^ this should get a variable where id=5391997 is set
      dataType: 'json',  
      success: function(data) {
          this.setState({temp: data.main.temp});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState:function(){
    return{
      cities:[
        { 
          name: "San Francisco",
          id: 5391997,
          temp: 50,  // << this should receive value from ajax call
          UTCOffset:-7,
          address: 999 Nathan Lane,
          phone: 555-5555
        },
        // 12 more city objects in this array, removed for brevity
    ]}
},
render: function() {
    console.log(this.state.temp); // << this returns the right temp
    // for San Francisco, because I hardcoded the value into the url
    return(
        <div className="city-grid">
        {this.state.cities.map(function(city,i){
          return(
            <CityRow key={i} name={city.name} temp={city.temp}
            UTCOffset={city.UTCOffset} address={city.address} 
            phone={city.phone}/>
          );
        })}
      </div>
    );
  }
});

module.exports = CityGrid;

我的问题:

  1. 如何提取临时值?在我的渲染函数中,console.log 返回 JSON 对象,这意味着数据已绑定(bind)并且可以在我的渲染函数中访问。但是,当我尝试获取温度时(我希望温度类似于 this.state.data.main.temp),我收到“数据未定义”的错误。然后,我希望能够在我的城市对象中为 12 个城市中的每一个城市设置此值,id: 5391997

更新 ^^ 这已解决:@dkurbz 建议在我的 ajax 成功方法中将状态设置为 temp 对我来说效果很好。

  • 我还面临着如何为每个城市设置唯一的网址的挑战。在我的 ajax 调用中,有 id=5391997,我想从城市对象中获取它,并将我的 ajax url 更改为 'baseURl' + this.props.id + '&units=imperial '。我完全不知道如何做到这一点。
  • 更新 ^^ 这是我目前陷入困境的地方。

    最佳答案

    这可能有一些错误,但我认为它应该让你非常接近。

    var React = require("react");
    var $ = require("jquery");
    
    var City = React.createClass({
        propTypes: {
            id: React.PropTypes.string.isRequired,
            units: React.PropTypes.string
        },
    
        getInitialState: function () {
            return {
                data: {},
                fetching: false
            };
        },
    
        getDefaultProps: function () {
            return {
                units: "imperial"
            };
        },
    
        render: function () {
            return (
                <div class="city">
                    {this.state.fetching ? "Downloading data..." : this.state.data.main.temp}
                </div>
            );
        },
    
        componentWillMount: function () {
            $.ajax({
                url: "http://api.openweathermap.org/data/2.5/weather?id="+this.props.id+"&units="+this.props.units,
                dataType: "json",
                beforeSend: function () {
                    this.setState({fetching: true});
                },
                success: function (data) {
                    this.setState({data: data});
                },
                error: function (xhr, status, err) {
                    console.error(xhr, status, err.toString());
                },
                complete: function () {
                    this.setState({fetching: false});
                },
                context: this
            });
        }
    });
    
    var CityGrid = React.createClass({
        propTypes: {
            cityIds: React.PropTypes.array.isRequired
        },
    
        renderCity: function (cityId) {
            return <City id={cityId} />;
        },
    
        render: function () {
            return (
                <div class="city-grid">
                    {this.props.cityIds.map(this.renderCity)}
                </div>
            );
        }
    });
    

    话虽这么说...这不是正确的解决方案。 ajax 调用应该移到组件之外(您是否研究过 Flux 或其他一些可以为您提供模型或存储概念的库?),然后返回的“数据”应该被转换/规范化为平面以某种方式构造,然后作为 props 传递给 City 组件(并且只有有意义/你关心的 props)。这样,城市组件就可以不知道其数据来自何处。理论上,您应该能够使用来自其他来源、多个来源、虚拟数据等的一些数据来渲染城市。但我不会为您编写所有这些数据;)

    关于javascript - 使用 Ajax 在 React 中打开天气数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32898002/

    相关文章:

    javascript - 不在 for 循环内执行的链方法

    javascript - jQuery 表单验证 - phoneUS 和默认消息样式

    java - Play 操作不响应发布的 json

    php - 如何将文本转换为图像,然后垂直旋转

    c# - 在 C# 中反序列化 JSON 日期时出现问题 - 添加 2 小时

    c# - 使用 Json.Net 仅序列化简单类型

    javascript - Deezer Javascript SDK pause() 方法在 iOS 上不起作用

    javascript - 如何在大型 php 网站中组织一些 javascript

    jquery - AngularJS 和指令的初学者问题 - 包装 jQuery 组件

    javascript - Jquery UI 可拖动不会第一次拖动