LoginSignup
3

More than 5 years have passed since last update.

Reactで非同期に現地を取得する

Last updated at Posted at 2018-05-08

概略

ReactとReduxとFirebaseを使ったアプリを書いているのですが,このたび 任意のタイミングで現在地を取得 することになりました.
現在地の取得には時間がかかるので非同期処理として扱うべきなので,今回はReact+Redux環境でよく使われるというredux-thunkの導入とその利用法について書きます.

導入

yarnを使ってredux-thunkを入れましょう.npmでもflatにインストールできるようになって久しいですが,yarnの方が高速で更にセキュアに入れてくれます(参考: npm vs yarn).

yarn add react-thunk

利用法

storeを生成しているところで,以下のようにReduxと混ぜて使います.

index.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducers';

const store = createStore(
  reducer,
  applyMiddleware(thunk),
);

次に,アクションに非同期処理を書いていきます.
...が,Storeを弄るコードと混ざって見づらくなるので,middlewareに本命の非同期処理を書いてactionから呼ぶようにしました.

actions/index.js
import { getPosition } from '../middlewares';

export const getPresentLocation = () => {
  return async dispatch => {
    try {
      const position = await getPosition(); //middlewareで非同期処理
      await setPresentLocation(position); //他のアクションでstoreに結果を保存
    } catch(e) {
      alert(e)
    }
  }
};
middlewares/index.js
export const getPosition = () => new Promise(resolve, reject) => {
  if(!navigator.geolocation) {
    reject("このブラウザは現在地の取得に対応していません:(");
  }

  navigator.geolocation.getCurrentPosition(position => resolve({
    lat: position.coords.latitude,
    lng: position.coords.longitude,
  }), e => reject(`エラー(${e.code}): ${e.message}`));
};

あとは,Storeを弄るのと同じようにdispatchでその非同期処理を行っている関数を呼ぶだけです.

components/main.js
import React from 'react';
import getPresentLocation from '../actions';

const main = ({ dispatch }) => (
  <button onClick={dispatch(getPresentLocation())}>
    現在地取得!
  </button>
);

export default connect()(main);

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3