Bulid Web application use Google Maps
此文章根据Tutorialzine教程实践,具体代码可参考Github
React.js
自正式发布以来,一直都是热门话题就不多讨论了,官方教程可参考React中文社区或者加入由@题叶推广的React-China社区
React组件结构设计
- App : 最主要的部分,它包含用于可以由像搜索的用户执行的操作的方法,增加一个位置到收藏夹等等。的其它组分内嵌套
- CurrentLocation : 呈现在地图中的当前被访问的地址。地址可以通过点击星标可以添加或删除收藏夹
- LocationList : 展示用户Start的LocationItem
- LocationItem : 是一个单独的位置。当它被点击,其相应的地址被搜索到并在地图上突出显示
- Map : 集成了GMaps实现库,并呈现从谷歌地图的地图
- Search : 是缠绕在搜索表单的成分。当它被提交,搜索位置被触发
具体代码实现
App.js
var React = require('react');
var Search = require('./Search');
var Map = require('./Map');
var CurrentLocation = require('./CurrentLocation');
var LocationList = require('./LocationList');
var App = React.createClass({
getInitialState(){
// 使用localStorage(本地存储)存储喜爱的位置
var favorites = [];
if(localStorage.favorites){
favorites = JSON.parse(localStorage.favorites);
}
// 默认初始化地址是巴黎
return {
favorites: favorites,
currentAddress: 'Paris, France',
mapCoordinates: {
lat: 48.856614,
lng: 2.3522219
}
};
},
toggleFavorite(address){
if(this.isAddressInFavorites(address)){
this.removeFromFavorites(address);
}
else{
this.addToFavorites(address);
}
},
addToFavorites(address){
var favorites = this.state.favorites;
favorites.push({
address: address,
timestamp: Date.now()
});
this.setState({
favorites: favorites
});
localStorage.favorites = JSON.stringify(favorites);
},
removeFromFavorites(address){
var favorites = this.state.favorites;
var index = -1;
for(var i = 0; i < favorites.length; i++){
if(favorites[i].address == address){
index = i;
break;
}
}
// 如果用户点击取消start,从喜欢的arra中删除它
if(index !== -1){
favorites.splice(index, 1);
this.setState({
favorites: favorites
});
localStorage.favorites = JSON.stringify(favorites);
}
},
isAddressInFavorites(address){
var favorites = this.state.favorites;
for(var i = 0; i < favorites.length; i++){
if(favorites[i].address == address){
return true;
}
}
return false;
},
searchForAddress(address){
var self = this;
// 这里是调用Google Maps API的部分,将会使用到Map.js的GMaps' geocode functionality
GMaps.geocode({
address: address,
callback: function(results, status) {
if (status !== 'OK') return;
var latlng = results[0].geometry.location;
self.setState({
currentAddress: results[0].formatted_address,
mapCoordinates: {
lat: latlng.lat(),
lng: latlng.lng()
}
});
}
});
},
render(){
return (
<div>
<h1>Your Google Maps Locations</h1>
<Search onSearch={this.searchForAddress} />
<Map lat={this.state.mapCoordinates.lat} lng={this.state.mapCoordinates.lng} />
<CurrentLocation address={this.state.currentAddress}
favorite={this.isAddressInFavorites(this.state.currentAddress)}
onFavoriteToggle={this.toggleFavorite} />
<LocationList locations={this.state.favorites} activeLocationAddress={this.state.currentAddress}
onClick={this.searchForAddress} />
</div>
);
}
});
module.exports = App;
CurrentLocation.js
var React = require('react');
var CurrentLocation = React.createClass({
toggleFavorite(){
this.props.onFavoriteToggle(this.props.address);
},
render(){
var starClassName = "glyphicon glyphicon-star-empty";
if(this.props.favorite){
starClassName = "glyphicon glyphicon-star";
}
return (
<div className="col-xs-12 col-md-6 col-md-offset-3 current-location">
<h4 id="save-location">{this.props.address}</h4>
<span className={starClassName} onClick={this.toggleFavorite} aria-hidden="true"></span>
</div>
);
}
});
module.exports = CurrentLocation;
LocationList.js
var React = require('react');
var LocationItem = require('./LocationItem');
var LocationList = React.createClass({
render(){
var self = this;
var locations = this.props.locations.map(function(l){
var active = self.props.activeLocationAddress == l.address;
// 在这个function中将会回调一个onClick
// LocationList 显示每个 LocationItem.
return <LocationItem address={l.address} timestamp={l.timestamp}
active={active} onClick={self.props.onClick} />
});
if(!locations.length){
return null;
}
return (
<div className="list-group col-xs-12 col-md-6 col-md-offset-3">
<span className="list-group-item active">Saved Locations</span>
{locations}
</div>
)
}
});
module.exports = LocationList;
LocationItem.js
var React = require('react');
var LocationItem = require('./LocationItem');
var moment = require('moment');
var LocationItem = React.createClass({
handleClick(){
this.props.onClick(this.props.address);
},
render(){
var cn = "list-group-item";
if(this.props.active){
cn += " active-location";
}
return (
<a className={cn} onClick={this.handleClick}>
{this.props.address}
<span className="createdAt">{ moment(this.props.timestamp).fromNow() }</span>
<span className="glyphicon glyphicon-menu-right"></span>
</a>
)
}
});
module.exports = LocationItem;
Map.js
var React = require('react');
var Map = React.createClass({
componentDidMount(){
this.componentDidUpdate();
},
componentDidUpdate(){
if(this.lastLat == this.props.lat && this.lastLng == this.props.lng){
return;
}
this.lastLat = this.props.lat;
this.lastLng = this.props.lng
var map = new GMaps({
el: '#map',
lat: this.props.lat,
lng: this.props.lng
});
// Adding a marker to the location we are showing
map.addMarker({
lat: this.props.lat,
lng: this.props.lng
});
},
render(){
return (
<div className="map-holder">
<p>Loading...</p>
<div id="map"></div>
</div>
);
}
});
module.exports = Map;
Search.js
var React = require('react');
var Search = React.createClass({
getInitialState() {
return { value: '' };
},
handleChange(event) {
this.setState({value: event.target.value});
},
handleSubmit(event){
event.preventDefault();
// 当提交表单时,调用传递到组件的onSearch回调
this.props.onSearch(this.state.value);
// Unfocus文本输入字段
this.getDOMNode().querySelector('input').blur();
},
render() {
return (
<form id="geocoding_form" className="form-horizontal" onSubmit={this.handleSubmit}>
<div className="form-group">
<div className="col-xs-12 col-md-6 col-md-offset-3">
<div className="input-group">
<input type="text" className="form-control" id="address" placeholder="Find a location..."
value={this.state.value} onChange={this.handleChange} />
<span className="input-group-btn">
<span className="glyphicon glyphicon-search" aria-hidden="true"></span>
</span>
</div>
</div>
</div>
</form>
);
}
});
module.exports = Search;
main.js
var React = require('react');
var App = require('./components/App');
React.render(
<App />,
document.body
);
总结
从一个初学者的佳都来看,使用React最重要的就是Compoent结构设计,还有就是被调用组件与组件之间的props,state和回调事件函数,附一张结构图帮助理解结构设计
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。