거의 알고리즘 일기장

react native location permission hook (useLocation) 본문

react-native

react native location permission hook (useLocation)

건우권 2021. 11. 22. 17:54

앱 초기 시작시에 location permission 체킹과 location값을 받을때 편할거 같아 만들어 보았다.


useLocation.ts

import React, { useEffect, useState } from "react";
import * as Location from "expo-location";

/**
 * useLocation
 * 1. 위치 권한 받고
 * 2. 권한 O일 경우: location값 반환
 * 3. 권한 X일 경우: errorMsg값 반환
 * - return: location, loading, isLocationPermission, erorMsg
 */

const useLocation = () => {
  const [isPermission, setIsPermission] = useState(false);
  const [response, setResponse] = useState<Location.LocationObject>();
  const [errorMsg, setErrorMsg] = useState("");
  const [isLoadingComplete, setIsLoadingComplete] = useState(false);

  useEffect(() => {
    (async () => {
      setIsLoadingComplete(false);
      let { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== "granted") {
        setErrorMsg("Permission to access location was denied");
        setIsPermission(false);
        return;
      }

      let location = await Location.getCurrentPositionAsync({
        accuracy: Location.Accuracy.Balanced,
      });
      setResponse(location);
      setIsPermission(true);
      setIsLoadingComplete(true);
    })();
  }, []);

  return {
    isPermission,
    response,
    isLoadingComplete,
    errorMsg,
  };
};

export default useLocation;

사용법

내가 사용했던 경우는 앱 실행에 있어서 위치 권한과 위치를 받고 못받고에 따라 분기 실행이 되었기 때문에, 초기 app동작시 location permission을 체킹하고 location 값들을 recoil atom값으로 넣어뒀다.

import { StatusBar } from "expo-status-bar";
import React, { useEffect, useState } from "react";
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";

import useCachedResources from "@hooks/useCachedResources";
import { RecoilRoot, useSetRecoilState } from "recoil";
import View from "@atoms/View";
import useLocation from "@hooks/useLocation";
import { IsLocationPermissionState, LocationState } from "@state";

export default function App() {
  const isLoadingCompleteCachedResources = useCachedResources();

  if (!isLoadingCompleteCachedResources) {
    return null;
  } else {
    return (
      <RecoilRoot>
        <LocationPermission>
         {... 컴포넌트들}
        </LocationPermission>
      </RecoilRoot>
    );
  }
}

const LocationPermission = (
  props: Readonly<{
    children?: React.ReactNode;
  }>
) => {
  const { isPermission, response, isLoadingComplete, errorMsg } = useLocation();
  const setIsPermission = useSetRecoilState(IsLocationPermissionState);
  const setLocation = useSetRecoilState(LocationState);

  useEffect(() => {
    if (isLoadingComplete) {
      setIsPermission(isPermission);
      setLocation(response);
    }
  }, [isLoadingComplete]);

  if (!isLoadingComplete) {
    return null;
  } else {
    return <View style={{ flex: 1 }} {...props} />;
  }
};

 

반응형
Comments