在反应中使用道具

问题描述:

我使用API​​中的数据构建应用程序,我想在应用程序中包含用户的纬度和经度。在反应中使用道具

我的应用程序在两个文件:app.jsmain.js

app.js我呈现这样的组件:

render(<Main source="https://api.darksky.net/forecast/apikey/latitude,longitude?units=auto"/>, document.getElementById('app')); 

的经度和纬度组件的源目前硬编码的,我想使这些动态。

在我main.js的组件使用这样的API:

componentDidMount() { 
this.serverRequest = $.get(this.props.source, function (result) { 
    this.setState({ 
    daily: result.daily.data, 
    hourly: result.hourly.data 
    }); 
}.bind(this)); 
} 

林能够获取使用HTML的地理定位用户的位置 - 这我想我应该在构造或componentWillMount商店,但我需要一种方法发送变量到app.js文件中的主要组件的源文件 - 我想我应该使用像道具一样的来源,但我不知道如何

这可能是一个很好的方法来传递经度和纬度到你的组件作为道具,并在组件中组装URL:

render(<Main longitude={longitude} latitude={latitude} />, document.getElementById('app')); 

componentDidMount() { 
    const url = `https://api.darksky.net/forecast/apikey/${this.props.latitude},${this.props.longitude}?units=auto`; 
    this.serverRequest = $.get(url, function (result) { 
     this.setState({ 
      daily: result.daily.data, 
      hourly: result.hourly.data 
     }); 
    }.bind(this)); 
} 
+0

您需要首先得到它是一个异步操作的坐标。 – pawel

+0

这工作,谢谢! :)是否可以在componentDidMount中放置地理位置以获取此处的经度和纬度? – frisk0

+0

当然,您可以简单地在组件的componentDidMount中进行调用,并启动地理位置回调的API调用。 – Timo

由于HTML地理位置是异步的render()调用可能进入的地理定位成功回调:

if (navigator.geolocation){ 

    function success(position) { 
    var latitude = position.coords.latitude; 
    var longitude = position.coords.longitude; 
    ReactDOM.render(
     <Main lat={ latitude } lon={ longitude } />, document.getElementById('container') 
    ); 
    }; 

    function error() { 
    console.log('geolocation error') 
    }; 


    navigator.geolocation.getCurrentPosition(success, error); 

} 

https://jsfiddle.net/69z2wepo/62204/

一个更高级的例子是高阶执行地理定位并将坐标传递给包装组件的组件。然后裹组件应检查坐标componentWillReceiveProps方法和做AJAX请求一旦道具都非空:

var GeoComponent = Component => React.createClass({ 
    getInitialState(){ 
     return { 
      lat : null, 
      lon : null 
     } 
    }, 

    componentDidMount(){ 
     navigator.geolocation.getCurrentPosition(this.setCoordinates, err => console.log(err)); 
    }, 

    setCoordinates(position){ 
     this.setState({ 
      lat : position.coords.latitude, 
      lon : position.coords.longitude 
     }) 
    }, 

    render(){ 
     return <Component lat={ this.state.lat } lon={ this.state.lon } { ...this.props } />; 
    } 
}); 

var Main = React.createClass({ 
    componentWillReceiveProps(nextProps){ 
     if(nextProps.lat && nextProps.lon){ 
      console.log('received coords!'); 
      /* 
       this.serverRequest = $.get(this.props.source, function (result) { 
       this.setState({ 
       daily: result.daily.data, 
       hourly: result.hourly.data 
       }); 
       }.bind(this)); 
      */ 
     } 
    }, 

    render(){ 
     return <div>Latitude: { this.props.lat }, Longitude: { this.props.lon }</div>; 
    } 

}); 


ReactDOM.render(
    React.createElement(GeoComponent(Main)), 
    document.getElementById('container') 
); 

https://jsfiddle.net/69z2wepo/62205/

+0

感谢您的回复。你是对的,我需要将render方法放在回调中以使其工作。不过,我认为这感觉有点慢,因为我必须等待地理位置处理 - 但我想这是唯一的方法? – frisk0

如果我没有记错的话,那么你想要达到的目标是有权访问app.js中的地理位置信息,不是吗?那么你为什么不在app.js内部获取用户地理位置并将其传递到Main?该代码会是这样的

app.js

let geo = null; 
navigator.geolocation.getCurrentPosition(function(pos) { 
    geo = pos; 

    render(<Main source={`https://api.darksky.net/forecast/apikey/${geo.coords.latitude},${geo.coords.longitude}?units=auto`}/>, document.getElementById('app')); 

    // Below use user's geolocation info as you wish 
}); 

或者,如果你想获得用户的地理位置信息之前,使一些占位符,那么你可以让主要成分做大部分的事情,传递回调主更新地理位置信息,以app.js

app.js

render(<Main updateGeolocation={geo => { /* do stuffs with geo */ }} />, document.getElementById('app')); 

个main.js

componentDidMount() { 
navigator.geolocation.getCurrentPosition(function(pos) { 
    this.serverRequest = $.get(`https://api.darksky.net/forecast/apikey/${pos.coords.latitude},${pos.coords.longitude}?units=auto`, function (result) { 
    this.setState({ 
    daily: result.daily.data, 
    hourly: result.hourly.data 
    }); 
    }.bind(this)); 

    this.props.updateGeolocation(pos); 
} 
}