React-native와 Expo를 이용한 날씨앱 만들기

Hyuno Choi·2021년 1월 2일
0
post-thumbnail

소스 코드: https://github.com/soonitoon/get-weather

이 글은 Nomad Coder"React Native로 날씨앱 만들기" 강의를 바탕으로 작성되었습니다.


2021년 1월 3일 일요일 새벽

파이썬으로 print("hello world") 를 입력한지 어느덧 1년이 되어가는 시점에 기술 블로그라는 이름의 복습노트를 만들게 되었습니다.
프론트엔드 개발자를 목표로 정하고 나서 "노마드 코더"의 강의 영상을 보며 만든 네 번째 프로젝트입니다.

제목과 같이 React-native와 Expo를 사용하여 간단한 날씨앱을 만들어 보았습니다.
필요한 준비물은 세 가지였습니다.

  • Node.js
  • NPM
  • Expo CLI

프로젝트를 생성할 경로에서 $ expo init을 입력해 새 프로젝트를 생성했습니다.

개요

간단한 날씨앱인 "get weather"는 사용자의 위치를 얻어 현재 날씨와 기온, 간단한 코멘트를 보여줍니다.

사용자의 위치를 파악해 실시간 날씨 정보를 알려주는 기능을 구현하기 위해서 필요한 두 가지는 사용자의 위치와 위치에 기반한 날씨 정보였습니다.
사용자 위치의 경우 expo-location 라이브러리의 Location을 사용했고, 날씨 정보의 경우 OpenWeather API를 활용했습니다.

날씨앱에서 렌더링 해야할 화면은 크게 두 가지로, 로딩 화면과 현재 날씨 정보를 보여주는 화면입니다.

구성

프로젝트의 구성은 크게 메인 컴포넌트가 위치한 App.js와 로딩 화면을 담당하는 Loading.js, 날씨 정보를 보여주는 화면을 담당하는 Weather.js로 이루어져 있습니다.
앱을 시작하면 로딩 화면이 나오고, 이후 메인 컴포넌트에서 얻은 날씨 정보를 Weather 함수에 prop으로 보내 해당 날씨 화면을 출력합니다.

App.js

메인 컴포넌트의 render()함수는 state 중 isLoading을 가져와 만약 isLoading이 true라면 Loading 화면을 출력하고, 그렇지 않으면 날씨 정보 화면을 출력합니다. 이 부분은 javaScript의 삼항 연산자로 구현하였습니다.

로딩 화면이 렌더링 되고 컴포넌트가 Mount 상태가 되면 getLocation 함수를 호출해 사용자의 위치 정보를 가져옵니다.

getLocation은 비동기 처리 함수로, requestPermissionsAsync 함수로 사용자에게 위치 정보 권한을 묻습니다.
이후 사용자에게 승낙을 받으면 getCurrentPositionAsync 함수로 사용자의 위도와 경도를 받아 getWeather 함수에 인자로 넘겨줍니다.
만약 사용자가 위치 권한을 주지 않으면 catch 구문으로 넘어가 경고창을 띄우게 됩니다.

getWeather 함수는 비동기 처리 함수로, 위도와 경도를 받아 OpenWeather API에서 위도와 경도에 기반한 날씨 정보를 받아옵니다.
이후 메인 컴포넌트의 state에서 isLoading을 false로 바꿔 날씨 정보 화면으로 넘어갈 수 있도록 하고, condition, temp를 API 데이터에서 받아와 날씨 정보 화면에 props로 넘겨줍니다.

Loading.js

로딩 화면은 텍스트가 떠있는 간단한 화면으로, 배경색이 밝기 때문에 react-native 라이브러리의 StatusBar를 사용하여 상태바를 어둡게 만들었습니다.

Weather.js

prop-types 라이브러리를 사용해 먼저 Weather 함수가 받는 prop들을 검사했습니다. temp는 기온 정보이므로 자료형은 number로, 필요 여부는 "필요함"으로 설정했습니다. condition은 날씨 정보로, OpenWeather API에서 보내주는 날씨 상태 중 하나인지 검사하도록 했습니다.

각 날씨 상태에 따라 바꾸어야 할 화면 설정들은 weatherOptions 객체로 만들어놓았습니다. 예를 들어 현재 condition으로 "Haze"가 들어왔다면, 화면에 표시해야 할 아이콘과 코멘트, 스타일은 다음과 같습니다.

화면 전체 Gradient 효과를 위해 expo-linear-gradient 라이브러리의 LinearGradient로 return할 요소 전체를 감싸주었습니다. 그라디언트의 시작 색과 끝 색은 condition 값에 따라 weatherOptions 객체에 저장되어있는 값을 꺼내옵니다.

날씨 아이콘은 @expo/vector-icons 라이브러리의 MaterialCommunityIcons을 사용했습니다. 여기에서도 그라디언트와 같이 표시해야 할 아이콘, 코멘트를 weatherOptions 객체에서 condition 값에 따라 꺼내쓰도록 했습니다.

비고 및 고찰

HTML, CSS 및 javaScript를 통해 기초적인 웹 사이트를 만들어보고, React로 첫 웹 페이지를 만들어 본 이후 만든 첫 번째 어플리케이션입니다.
Expo를 이용해 실시간으로 수정 사항이 스마트폰에 반영되는 것도 재미있었고, 스마트폰의 화면이 작다보니 얼마 안 되는 구성물로 멋진 결과를 얻을 수 있어 흥미로웠습니다.

단 두 번의 React 제작 경험으로 React를 완전히 이해할 수는 없을 것입니다. 아직은 바닐라 javascript 대비 React의 장점을 제대로 깨닫지 못했지만 앞으로 다른 프로젝트를 진행하면서 실력을 향상시킬 계획입니다.

마지막 정리

  • componentDidMount()는 render()가 실행된 후에 실행된다.
  • 날씨에 따른 화면 설정들을 객체로 만들어놓으면 모든 날씨 화면을 만들지 않아도 된다.
  • PropTypes로 prop을 검사하면 어떤 prop이 어떤 문제가 있는지 알 수 있다.
  • StatusBar로 스마트폰의 상태바를 바꿀 수 있다.
  • react-native의 style 중 flex가 가지는 숫자는 화면에서 차지하는 비율을 뜻한다.

git: https://github.com/soonitoon

profile
프론트엔드 웹 개발자를 목표로 하고 있습니다.

0개의 댓글