openlayersでReactを試す


Reactレビューするために、最近触っているopenlayersで試した。

とりあえず地図を表示だけということで[openlayersのチュートリアル](https://openlayers.org/en/latest/doc/tutorials/bundle.html)のようなのを試したが、やっぱりつまったのでメモとして残しておく。

## 例
create-react-appで開発環境構築


src
├── App.css
├── App.js
├── App.test.js
├── Map
│   ├── MapPane.css
│   └── MapPane.js
├── index.css
├── index.js
├── logo.svg
├── reportWebVitals.js
└── setupTests.js

作成したのはMapフォルダとそのファイル、App.jsを修正

```jsx:src/Map/MapPane.js
import React, { useEffect, useRef, useState } from 'react';
// OpenLayers読み込み
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import { fromLonLat } from 'ol/proj';
import OlSourceOSM from "ol/source/OSM";

import 'ol/ol.css';
import './MapPane.css';

const MapPane = () => {
	const mapRef = useRef();

  const [map,setMap] = useState(null);

  // on component mount
	useEffect(() => {
       let options = {
         view: new View({
           center: fromLonLat([139.767, 35.681]),
           zoom: 14,
         }),
         layers: [
           new TileLayer({
            source: new OlSourceOSM(),
           }),
        ],
       };
		let mapObject = new Map(options);
        //注目の２行!
		mapObject.setTarget(mapRef.current);
		setMap(mapObject);

		return () => mapObject.setTarget(undefined);
	}, []);

    return (
      <div className={'map'} ref={mapRef} />
    )


}

export default MapPane;

```
```src/Map/MapPane.css
.map {
  z-index: 0;
  height: 1000px;
  text-align: left;
}
```
```jsx:src/App.js
import React from "react"

import MapPane from "./Map/MapPane";


 const App = () =>{

  return (

  <div>
			<MapPane />

 </div>
  );
}

export default App;

```

![スクリーンショット 2021-05-25 20.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/fadf2b50-24bb-fb82-028b-6e97f1fd4da7.png)

## ポイント
写経ばかりだったせいか、いきなり関数コンポーネントを使用すると手が止まった。
### useStateの使用
この関数を実行することでコンポーネント内で状態を扱える
→まあ納得

### useRefの使用

```
		mapObject.setTarget(mapRef.current);
```
これがよくわからない。今までもあまり使っていない。これで大きくつまずいた。

```
<div id="map"></div>
```

がないのだが、代替としてマッピングしているイメージなのだろう。


### useEffect
下記説明でイメージがわいた。いきなり使用すると手が止まる。

```js
  useEffect(() => {
    // 初回レンダリング時に実行する処理を書く
    // comopnentDidMount相当

    return () => {
      // コンポーネントが削除される時に実行する処理を書く
      // componentWillUnmount相当
    };
  }, []);
```

### 追記
最初は下記の方がいいかもしれない。
openlayerの公式ページに従い、idへセットしている。

```jsx:src/Map/MapPane.js
import React, { useEffect, useState } from 'react';
// OpenLayers読み込み
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import { fromLonLat } from 'ol/proj';
import OlSourceOSM from "ol/source/OSM";

import 'ol/ol.css';
import './MapPane.css';

const MapPane = () => {

  const [map,setMap] = useState(null);

  // on component mount
    useEffect(() => {
      let mapObject = new Map({

        view: new View({
           center: fromLonLat([139.767, 35.681]),
           zoom: 14,
         }),
         layers: [
           new TileLayer({
            source: new OlSourceOSM(),
           }),
         ],
         target:'map'
       });
        // let mapObject = new Map(options);
        //注目の２行!
        // mapObject.setTarget("map");
        setMap(mapObject);

        return () => mapObject.setTarget(undefined);
    }, []);

    return (
      <div className={'map'} id="map" />
    )


}
```

### 参考記事
・[ReactでプレーンなLeafletとMapbox GL JSとOpenLayersの開発環境を構築してみた](https://qiita.com/dayjournal/items/7d25e703facad3494fd9)

・[スネークゲームを作って学ぶ React Hooks API での状態管理](https://www.techpit.jp/courses/127)
　(techpit教材)