REACT を操作しています Maps API for JavaScript を React の機能コンポーネントと組み合わせることで、シームレスなユーザー体験を提供し、メンテナンスが容易な対話型の Web アプリケーションを作成できます。これは、アプリケーション全体でコンポーネントを再利用してコードの重複を削減できるためです。
マップを特定のビジネスニーズに合わせて適切に調整するには、多くのカスタマイズが必要になります。 マップを React コンポーネントとして構築することで、最も複雑なカスタマイズも 1 つのコンポーネントにカプセル化でき、マップの管理と再利用が容易になります。
チュートリアルの目的 このチュートリアルの目的は、レストランのリストを表示する React アプリケーションを作成し、レストランのエントリをクリックしてその場所を表示し、現在の場所から最速のルートを見つけることができるようにすることです。
このチュートリアルでは、次の React コンポーネントを作成する方法について説明します。
App
- メインコンポーネントとして機能し、ブラウザウィンドウで他のすべてのコンポーネントをレンダリングします。 RestaurantList
- ユーザーの近隣にあるレストランを一覧表示します。 RestaurantEntry
- 一覧表内のレストランのエントリを表します。 Map
- Maps API for JavaScript を使用してマップをレンダリングし、ユーザーがレストランのエントリをクリックしたときに最速ルートを計算します。 次の図は、これらの反応コンポーネントを一覧表で示したものです。
このチュートリアルを完了する方法については、次のセクションを参照してください。また、 React 機能コンポーネントを使用して Maps API for JavaScript を使用し、動的でインタラクティブな Web アプリケーションを作成する方法についても理解を深めることができます。
作業を開始する前に このチュートリアルを完了する前に、次の前提条件を満たしていることを確認してください。
HTML 、 CSS 、および JavaScript についての基本的な理解 Node.js に精通し、機能的なコンポーネントとフックに反応します さらに、 HERE platform アカウントを取得します 最後に、任意のテキストエディタまたは IDE (Visual Studio コード、サブライムテキスト、 Atom など ) がインストールされていることを確認します。 Create React アプリ 環境を使用して、新しい React アプリケーションを設定します。 この環境では、はじめにが単一ページのアプリケーションを迅速に構築できます。
ターミナルウィンドウを開き、新しい REACT プロジェクトを作成するディレクトリに移動します。
create-react-app
次のコマンドを実行して、新しい REACT プロジェクトを開始します。
npx create-react-app my-food-delivery-app
結果 : 上記の呼び出しによって、アプリケーションの起動に必要な足場が作成されます。 my-food-delivery-app
ディレクトリ内のディレクトリ構造には、次の構造があり src
ます( react コンポーネントはディレクトリに存在します)。
my-food-delivery-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── ...
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── reportServiceVitals.js
└── setupTests.js
次のコマンドを実行して、新しく作成したディレクトリにナビゲートします。
cd my-food-delivery-app
グローバル変数に多塗りが使用されない ようにアプリを設定します。
注 の最新バージョン create-react-app
では、 webpack 5 が使用され、グローバル変数にポリフィルを使用するように設定されています。 このデフォルトオプションは、 Maps API for JavaScript と互換性がありません。
次のコマンドを実行して、アプリを取り出します。
npm run eject
確認のメッセージが表示されたら Y
、キーを押してイジェクトを確認します。
config
ディレクトリから、任意のテキストエディタを使用 webpack.config.js
してファイルを開きます。
次 の例に示すように、module.exports
オブジェクト内にnode
という新しいプロパティを追加し、その値をfalse
に設定します。
module. exports = {
node : {
global : false
}
} ;
ファイルを保存します。
maps-api-for-javascript
NPM パッケージをインストール :
次のコマンドを実行して、 NPM 設定にレジストリエントリを追加します。
npm config set @here:registry https://repo.platform.here.com/artifactory/api/npm/maps-api-for-javascript/
@here
次のコマンドを実行して、名前空間から API パッケージをインストールします。
npm install @here/maps-api-for-javascript
結果 : 環境のセットアップが完了し、サンプルアプリケーションのビルドに必要なすべてのパッケージがインストールされます。
次のコマンドを実行して、環境のセットアップが正常に完了したことを確認します。
npm start
結果 : このコマンド を使用すると、ブラウザの http://localhost:3000 アドレスにある「ホットリロード」機能を使用して開発サーバが起動されます。 さらに、ターミナルに Compiled successfully!
メッセージが表示されます。
地図を表示する反応機能コンポーネントを追加します useRef
および useEffect
フックを使用して、マップを保持する< div>
要素をレンダリングする機能コンポーネントを作成します。 useRef
フックによって、 div 要素への参照と、マップインスタンスへの参照が作成されます。 useEffect
フックは、マップインスタンスがすでに作成されているかどうかを確認します。 そうでない場合、フックは Maps API for JavaScript を使用して新しいマップを作成し、初期マッププロパティ ( 中央、ズーム レベルなど ) を設定して、マップ参照を設定します。 フックを使用 Behavior
すると、地図上でパンおよびズーム機能を有効にするオブジェクトも作成されます。
src
ディレクトリに新しい Maps.js
ファイルを作成します。
Maps.js
ファイルで 、 @here/maps-api-for-javascript
パッケージからReact
、useEffect
、useRef
、およびH
オブジェクトをインポートします。
import React, { useEffect, useRef } from 'react' ;
import H from '@here/maps-api-for-javascript' ;
Map
オブジェクト props
を引数として受け取る関数としてコンポーネントを定義します。
const Map = ( props ) => {
const mapRef = useRef ( null ) ;
const map = useRef ( null ) ;
const platform = useRef ( null )
const { apikey } = props;
}
注 Map
この関数は props
、オブジェクトから API キー を抽出し、 2 つの参照を作成します。 1 つはブラウザーでマップをレンダリングするマップ HTML 要素用で、もう 1 つは Maps API for JavaScript マップインスタンス用です。 useRef
フックを使用すると、マップのインスタンスが 1 つだけ作成され、コンポーネントの不要な再レンダリングが防止されます。
Map
次 useEffect
の例に示すように、コンポーネント関数内でフックを定義します。
useEffect (
( ) => {
if ( ! map. current) {
platform. current = new H. service. Platform ( { apikey } ) ;
const rasterTileService = platform. current. getRasterTileService ( {
queryParams : {
style : "explore.day" ,
size : 512 ,
} ,
} ) ;
const rasterTileProvider = new H. service. rasterTile. Provider (
rasterTileService
) ;
const rasterTileLayer = new H. map. layer. TileLayer ( rasterTileProvider) ;
const newMap = new H. Map ( mapRef. current, rasterTileLayer, {
pixelRatio : window. devicePixelRatio,
center : {
lat : 64.144 ,
lng : - 21.94 ,
} ,
zoom : 14 ,
} ) ;
const behavior = new H. mapevents. Behavior (
new H. mapevents. MapEvents ( newMap)
) ;
map. current = newMap;
}
} ,
[ apikey]
) ;
return < div style= { { width : "100%" , height : "500px" } } ref= { mapRef} / > ;
ここで、
useEffect
フックは、マップインスタンスが作成されているかどうかを確認します。 そうでない場合、フックは H.Map
コンストラクタを使用して、指定されたオプションを使用して新しいオプションを作成します。 behavior
変数は H.mapevents.Behavior
、 H.mapevents.MapEvents
クラスおよびクラスを使用して、マップにパンおよびズームの動作を追加します。 map.current = NewMap
このステートメントは、新しく作成されたマップインスタンスを格納するようにマップ参照を更新します。 return ステートメントは 、適切なスタイルの< div>
要素と 、ref
属性がmapRef
参照に設定された要素を返します。 ファイルの最後に Map
、コンポーネントをデフォルトのエクスポートとしてエクスポートします。
export default Map;
このステートメントは、他のモジュールがこの機能コンポーネントをインポートして他のモジュールと統合できるようにします。
src
ディレクトリから App.js
ファイルを開きます。
ファイルの既定の内容を次のコードで置き換えます。
import Map from './Map' ;
import React, { useState } from 'react' ;
const apikey = 'Your API key'
function App ( ) {
return (
< div>
< Map apikey= { apikey} / >
< / div>
) ;
} ;
export default App;
このコード は、Map
コンポーネントを含むApp
コンポーネントをエクスポートしてレンダリングします。 Map
コンポーネントが ./Map
ファイルからインポートさ App
れ、コンポーネント内にレンダリングされます。 App
コンポーネントがレンダリングされると Map
、コンポーネントが表示 < div>
されます。コンポーネントは、 Maps API for JavaScript を使用してマップを作成し、要素内にレンダリングします。
ファイルを保存します。
結果 : React は、次の例に示すように、マップの機能コンポーネントをレンダリングします。
図 1. 反応する機能コンポーネント内の基本的なマップ ユーザーとレストランのデータを設定します ユーザーの現在の場所、およびユーザーの近隣にある複数のサンプルレストランの場所を設定します。
注 簡単にするために、これらの値は手動で設定され、ランタイム中に変更することはできません。 ただし、リアルタイムの地理位置情報データに基づいて動的に値を設定するようにコードを変更できます。
App.js
ファイルで、次の例に示すように、現在のユーザーの場所を設定する変数を作成します。
const userPosition = { lat : 64.1472 , lng : - 21.9398 } ;
同じファイルに、ユーザーの場所に近いレストランの名前と場所を設定するオブジェクトの配列を追加します。
const restaurantList = [
{
name : "The Fish Market" ,
location : { lat : 64.1508 , lng : - 21.9536 } ,
} ,
{
name : "Bæjarins Beztu Pylsur" ,
location : { lat : 64.1502 , lng : - 21.9519 } ,
} ,
{
name : "Grillmarkadurinn" ,
location : { lat : 64.1475 , lng : - 21.9347 } ,
} ,
{
name : "Kol Restaurant" ,
location : { lat : 64.1494 , lng : - 21.9337 } ,
} ,
] ;
ファイルを保存します。
React コンポーネントを定義して、レストランのエントリをグリッドで表示します RestaurantList
レストランのエントリを別々のコンポーネントとしてレンダリングするコンポーネントを設定します。
src
React プロジェクトフォルダのディレクトリで、という名前のファイルを作成 RestaurantList.js
し、そのファイルを任意のテキストエディタで開きます。
RestaurantList.js
ファイルで RestaurantEntry
、次の例に示すように、リスト内のレストランのエントリを表す機能コンポーネントを作成します。
function RestaurantEntry ( props ) {
const handleClick = ( ) => {
props. onClickHandler ( props. data. location) ;
} ;
const entryStyle = {
display : "inline-block" ,
padding : "10px" ,
margin : "5px" ,
border : "1px solid gray" ,
borderRadius : "5px" ,
cursor : "pointer" ,
} ;
return (
< div style= { entryStyle} onClick= { handleClick} >
{ props. data. name}
< / div>
) ;
}
ここで、
props
パラメータには、特定のレストランおよび onClickHandler
関数のデータが含まれています。 コンポーネントは < div>
、コンテンツとしてレストラン名を持つ要素を返します。 RestaurantList.js
ファイルに RestaurantList
、次の例に示すように、レストランのリストを表すという別の機能コンポーネントを追加します。
function RestaurantList ( props ) {
const entries = props. list;
const list = entries. map ( ( entry ) => {
return < RestaurantEntry data= { entry} onClickHandler= { props. onClickHandler} key= { Math. random ( ) } > < / RestaurantEntry>
} ) ;
return (
< div id= "restaurant-list" style= { { 'display' : 'grid' } } >
{ list}
< / div>
)
}
ここで、
props
このパラメータには list
、レストランのエントリの配列と onClickHandler
関数が含まれています。 entries
配列の各entry
要素が RestaurantEntry
コンポーネントになり 、entry
データがdata
prop として渡され、 props のonClickHandler
関数が onClickHandler
prop として渡されます。 を使用して、各コンポーネントに一意のキーも割り当て Math.random()
られます。 コンポーネントは 、id
属性がrestaurant-list
に設定された< div>
要素を返し ます。 コンポーネントは style
、属性を使用して、表示プロパティがに設定されたインライン CSS を適用 grid
します。 < div>
要素 RestaurantEntry
は、コンポーネントを含むリスト変数をレンダリングします。 RestaurantList.js
次の例に示すように、ファイルの最後に export ステートメントを追加します。
export default RestaurantList;
注 export
このステートメントを使用 RestaurantList
すると、他のモジュールまたはファイルでコンポーネントをインポートし、再利用可能なコンポーネントとして使用できます。
次 の例に示すように、App.js
ファイルで、RestaurantList
およびRestaurantEntry
コンポーネントをブラウザウィンドウに表示するようにApp
機能コンポーネントを更新します。
function App ( ) {
const [ restaurantPosition, setRestaurantPosition] = useState ( null ) ;
const onClickHandler_ = ( location ) => {
setRestaurantPosition ( location) ;
} ;
return (
< div>
< RestaurantList list= { restaurantList} onClickHandler= { onClickHandler_} / >
< Map
apikey= { apikey}
userPosition= { userPosition}
restaurantPosition= { restaurantPosition}
/ >
< / div>
) ;
}
ここで、
useState
フックによって状態変数restaurantPosition
と レストランの位置を更新する関数setRestaurantPosition
が作成されます。 の初期値 restaurantPosition
はに設定 null
されています。 onClickHandler_
この関数は、 restaurantPosition
呼び出されたときに状態変数を更新するコールバック関数です。 この関数は location パラメータを取り restaurantPosition
、その場所にを設定します。 このreturn
ステートメントは 、RestaurantList
コンポーネントと Map
コンポーネントをラップする< div>
要素を返します。 RestaurantList
コンポーネントは restaurantList
という名前の prop として配列を渡し list
、 onClickHandler_
関数はという名前の prop として渡さ onClickHandler
れます。 Map
コンポーネントは apikey
、userPosition
、、およびrestaurantPosition
の変数をプロパティとして渡します。 ファイルを保存します。
結果 : ブラウザウィンドウに RestaurantList
コンポーネントが表示されます。 このコンポーネント内では、次 RestaurantEntry
の図に示すように、各レストランが個別のコンポーネントとして表示されます。
REACT コンポーネント間の対話性を導入します インタラクティブ性を高めるため Map
に、ユーザーの位置を表すマーカー、レストランの位置を表すマーカー、およびそれらの間で計算された最速ルートを表示するようにコンポーネントを設定できます。 この設定は、ユーザーが RestaurantEntry
コンポーネントをクリックするとトリガされます。
Map.js
次 Map
の例に示すように、ファイルの関数で props オブジェクトを更新し、ユーザーおよびレストランの位置を抽出します。
const Map = ( props ) => {
const mapRef = useRef ( null ) ;
const map = useRef ( null ) ;
const platform = useRef ( null ) ;
const { apikey, userPosition, restaurantPosition } = props;
次 useEffect
の例に示すように、フックの dependencies 配列にユーザーとレストランの場所を追加します。
import { useEffect } from 'react' ;
const Map = ( props ) => {
useEffect ( ( ) => {
} ,
[ apiKey, userPosition, restaurantPosition] ) ;
} ;
次の例に示すように、現在のマップの中心を現在のユーザーの位置と同じ値に変更します。
const newMap = new H. Map (
mapRef. current,
rasterTileLayer, {
pixelRatio : window. devicePixelRatio,
center : userPosition,
zoom : 14 ,
} ,
) ;
マーカーアイコンのスタイルを設定する関数を定義します。
function getMarkerIcon ( color ) {
const svgCircle = ` <svg width="20" height="20" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g id="marker">
<circle cx="10" cy="10" r="7" fill=" ${ color} " stroke=" ${ color} " stroke-width="4" />
</g></svg> ` ;
return new H. map. Icon ( svgCircle, {
anchor : {
x : 10 ,
y : 10
}
} ) ;
}
HERE Routing API V8 を使用して、ユーザーとレストラン間の最速ルートを計算します。
function calculateRoute ( platform, map, start, destination ) {
function routeResponseHandler ( response ) {
const sections = response. routes[ 0 ] . sections;
const lineStrings = [ ] ;
sections. forEach ( ( section ) => {
lineStrings. push ( H . geo. LineString. fromFlexiblePolyline ( section. polyline) ) ;
} ) ;
const multiLineString = new H. geo. MultiLineString ( lineStrings) ;
const bounds = multiLineString. getBoundingBox ( ) ;
const routePolyline = new H. map. Polyline ( multiLineString, {
style : {
lineWidth : 5
}
} ) ;
map. removeObjects ( map. getObjects ( ) ) ;
map. addObject ( routePolyline) ;
map. addObjects ( [
new H. map. Marker ( start, {
icon : getMarkerIcon ( 'red' )
} ) ,
new H. map. Marker ( destination, {
icon : getMarkerIcon ( 'green' )
} )
] ) ;
}
const router = platform. getRoutingService ( null , 8 ) ;
const routingParams = {
'origin' : ` ${ start. lat} , ${ start. lng} ` ,
'destination' : ` ${ destination. lat} , ${ destination. lng} ` ,
'transportMode' : 'car' ,
'return' : 'polyline'
} ;
router. calculateRoute ( routingParams, routeResponseHandler, console. error) ;
}
このコードは、ルート計算プロセスを設定し、応答を処理して、計算されたルート、ユーザーマーカー、および宛先マーカーをマップに表示します。 詳細については、以下を参照してください。
Map
コンポーネントのuseEffect
フックにコードを追加して 、restaurantPosition
正しいかどうかを確認します。
if ( restaurantPosition) {
calculateRoute ( platform. current, map. current, userPosition, restaurantPosition) ;
}
restaurantPosition
が定義されている場合、コードはユーザーの位置からレストランの位置までのルートを計算して地図に表示します。
ファイルを保存します。
結果 : 次の例に示すように、ユーザーの場所と選択したレストランの間の最速ルートを計算できるようになりました。
チュートリアルの手順に従うことで、 Maps API for JavaScript を反応機能コンポーネントと統合して、位置情報ベースの機能をアプリケーションに組み込み、ユーザーの操作を処理する方法を学習しました。
任意 : アプリケーションのスタイルを設定します スタイリングの改善により、コンポーネントの魅力を高め、視覚的にユーザーにアピールすることで、アプリケーションをさらに改善できます。
たとえば、 CSS を使用すると App
、コンポーネント内の個 RestaurantEntry
々のコンポーネントの配置を調整してコンポーネントの視覚的な外観を改善できます。また、丸みのある境界線を使用して、マウスオーバー状態に基づいてボタンの色のバリエーションを追加し、各エントリの追加データを表示できます。 コンポーネントの上部にバナーを配置 RestaurantList
するなどの操作を行います。
次の図は、 このチュートリアルで作成した RestaurantList
コンポーネントおよびRestaurantEntry
コンポーネントに適用されているサンプルのスタイルを示しています。
詳細 については、 Cascading Style Sheets (CSS) のドキュメントを参照してください。
次のステップ その他の使用例の詳細について は、『 Maps API for JavaScript Guide 』 を参照してください。