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

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

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

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( 
{this.state.cities.map(function(city,i){ return( ); })}
); } }); module.exports = CityGrid;

我的问题:

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

更新 ^^这个解决了:@dkurbz建议将状态设置为我的ajax成功方法中的临时工作对我来说很好。

  1. 我也面临着如何为每个城市设置唯一url的挑战。 在我的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 ( 
{this.state.fetching ? "Downloading data..." : this.state.data.main.temp}
); }, 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 ; }, render: function () { return (
{this.props.cityIds.map(this.renderCity)}
); } });

话虽如此……这不是正确的解决方案。 应该将ajax调用移到组件之外(你看过Flux,还是其他一些可以给你模型或商店概念的库?),然后应该将返回的“数据”转换/标准化为一个单元结构以某种方式,然后传递给City组件作为道具(并且只有有意义/你关心的道具)。 这样,City组件可以不知道其数据来自何处。 从理论上讲,你应该能够使用来自其他来源,多个来源,虚拟数据等的一些数据来呈现一个城市。但是我不打算为你编写所有这些数据;)

在对data this.state.data之前, this.state.data是未定义的。 您可以通过不从this.state.data渲染任何内容来修复此问题,直到它被定义,或者在getInitialState设置data: {}