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和回调事件函数,附一张结构图帮助理解结构设计