icon안동민 개발노트

외부 API를 활용한 날씨 정보 앱 만들기


 이 실습에서는 OpenWeatherMap API를 사용하여 간단한 날씨 정보 앱을 만들어보겠습니다.

 이 과정을 통해 비동기 데이터 처리, API 요청, 상태 관리, 그리고 사용자 입력 처리 등 React 개발의 핵심 개념들을 실제로 적용해볼 수 있습니다.

1단계 : 프로젝트 설정

 먼저 새로운 React 프로젝트를 생성하고 필요한 dependencies를 설치합니다.

npx create-react-app weather-app
cd weather-app
npm install axios

2단계 : API 키 설정

 OpenWeatherMap API 키를 받아 .env 파일에 저장합니다.

.env
REACT_APP_WEATHER_API_KEY=your_api_key_here

3단계 : API 요청 함수 작성

 src 폴더에 api.js 파일을 생성하고 다음 내용을 작성합니다.

src/api.js
import axios from 'axios';
 
const API_KEY = process.env.REACT_APP_WEATHER_API_KEY;
const BASE_URL = 'https://api.openweathermap.org/data/2.5/weather';
 
export const getWeather = async (city) => {
  try {
    const response = await axios.get(BASE_URL, {
      params: {
        q: city,
        appid: API_KEY,
        units: 'metric'
      }
    });
    return response.data;
  } catch (error) {
    throw error;
  }
};

4단계 : 날씨 정보 컴포넌트 작성

 WeatherInfo.js 파일을 생성하고 다음 내용을 작성합니다.

src/WeatherInfo.js
import React from 'react';
 
function WeatherInfo({ data }) {
  return (
    <div>
      <h2>{data.name}, {data.sys.country}</h2>
      <div>Temperature: {data.main.temp}°C</div>
      <div>Weather: {data.weather[0].main}</div>
      <div>Description: {data.weather[0].description}</div>
    </div>
  );
}
 
export default WeatherInfo;

5단계 : 메인 App 컴포넌트 작성

 App.js 파일을 다음과 같이 수정합니다.

src/App.js
import React, { useState } from 'react';
import { getWeather } from './api';
import WeatherInfo from './WeatherInfo';
import './App.css';
 
function App() {
  const [city, setCity] = useState('');
  const [weather, setWeather] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
 
  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    setError(null);
    try {
      const data = await getWeather(city);
      setWeather(data);
    } catch (err) {
      setError('Failed to fetch weather data. Please try again.');
    } finally {
      setLoading(false);
    }
  };
 
  return (
    <div className="App">
      <h1>Weather App</h1>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={city}
          onChange={(e) => setCity(e.target.value)}
          placeholder="Enter city name"
          required
        />
        <button type="submit">Get Weather</button>
      </form>
      {loading && <div>Loading...</div>}
      {error && <div className="error">{error}</div>}
      {weather && <WeatherInfo data={weather} />}
    </div>
  );
}
 
export default App;

6단계 : 스타일링

 App.css 파일을 다음과 같이 수정하여 간단한 스타일을 적용합니다.

src/App.css
.App {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
  text-align: center;
}
 
form {
  margin-bottom: 20px;
}
 
input {
  padding: 10px;
  font-size: 16px;
  width: 200px;
}
 
button {
  padding: 10px 20px;
  font-size: 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  cursor: pointer;
}
 
.error {
  color: red;
  margin-bottom: 10px;
}

코드 설명

 1. API 요청 (api.js)

  • axios를 사용하여 OpenWeatherMap API에 GET 요청을 보냅니다.
  • 환경 변수를 통해 API 키를 안전하게 관리합니다.
  • 에러 처리를 포함하여 비동기 요청을 수행합니다.

 2. 날씨 정보 표시 (WeatherInfo.js)

  • API로부터 받은 데이터를 props로 전달받아 화면에 표시합니다.
  • 구조 분해 할당을 사용하여 필요한 데이터를 추출합니다.

 3. 메인 컴포넌트 (App.js)

  • useState 훅을 사용하여 city, weather, loading, error 상태를 관리합니다.
  • handleSubmit 함수에서 비동기 API 요청을 처리합니다.
  • 로딩 상태와 에러 처리를 구현하여 사용자에게 적절한 피드백을 제공합니다.
  • 조건부 렌더링을 사용하여 로딩 상태, 에러 메시지, 날씨 정보를 표시합니다.

작동 방식

  1. 사용자가 도시 이름을 입력하고 "Get Weather" 버튼을 클릭합니다.
  2. handleSubmit 함수가 호출되어 API 요청을 시작합니다.
  3. 로딩 중에는 "Loading..." 메시지가 표시됩니다.
  4. API 요청이 성공하면 WeatherInfo 컴포넌트를 통해 날씨 정보가 표시됩니다.
  5. 요청 실패 시 에러 메시지가 표시됩니다.

추가 개선 사항

  1. 자동 완성 기능 : 도시 이름 입력 시 자동 완성 기능을 추가하여 사용자 경험을 개선할 수 있습니다.
  2. 날씨 아이콘 : OpenWeatherMap에서 제공하는 날씨 아이콘을 표시하여 시각적 정보를 추가할 수 있습니다.
  3. 단위 전환 : 섭씨/화씨 온도 단위를 전환할 수 있는 기능을 추가할 수 있습니다.
  4. 위치 기반 날씨 : 사용자의 현재 위치를 기반으로 날씨 정보를 자동으로 표시하는 기능을 구현할 수 있습니다.
  5. 날씨 예보 : 현재 날씨뿐만 아니라 몇 일 간의 예보를 표시하도록 확장할 수 있습니다.
  6. 캐싱 : 자주 요청되는 도시의 날씨 정보를 캐싱하여 API 호출을 줄이고 성능을 개선할 수 있습니다.

 이 실습을 통해 우리는 React의 핵심 개념들을 실제 애플리케이션에 적용해보았습니다. 상태 관리, 비동기 데이터 처리, 조건부 렌더링, 그리고 사용자 입력 처리 등의 기술을 종합적으로 활용하여 실용적인 날씨 정보 앱을 만들었습니다.

 특히 axios를 사용한 API 요청, useState 훅을 통한 상태 관리, 그리고 async/await를 활용한 비동기 처리 등은 현대적인 React 애플리케이션 개발에서 필수적인 기술들입니다. 이러한 기술들을 능숙하게 다룰 수 있게 되면, 다양한 종류의 웹 애플리케이션을 효과적으로 개발할 수 있습니다.

 또한, 이 프로젝트는 확장성이 높아 추가적인 기능을 구현하며 React 학습을 계속할 수 있는 좋은 기반이 됩니다. 예를 들어, React Router를 도입하여 여러 페이지를 가진 앱으로 확장하거나, Redux나 Context API를 사용하여 더 복잡한 상태 관리를 구현해볼 수 있습니다.

 마지막으로, 실제 API를 사용하는 프로젝트를 통해 외부 서비스와의 통합, API 키 관리, 에러 처리 등 실제 개발 환경에서 마주치는 다양한 과제들을 경험해볼 수 있었습니다.

 이러한 경험은 실무에서 매우 중요하며, 더 복잡한 프로젝트를 수행할 때 큰 도움이 될 것입니다.