20일차

2024. 8. 19. 18:33FCB2O4

오늘은 날씨 api를 구현

 

구글에서 한참을 검색해 마음에 드는 css가 있어서 그걸 받아와서 구현

 

날씨 키는 여기서 회원가입 후 받아왔다

https://openweather.co.uk/

 

OpenWeather for business

Well-known Having served 6 mln customers, OpenWeather products can be found everywhere. See the 14k+ repositories on GitHub. View solutions --> Relevant We offer high-quality, hyperlocal data, considering the nuance of local climate. Read more --> Cost-eff

openweather.co.uk

 

 

Weather.js

import React, { useState, useEffect } from 'react';
import '../css/MainPage.css'; 

const DisplayWeather = (props) => {
    const cityValue = props.inputLocation;
    const key = '날씨 API 키';

    const [weatherValue, setWeatherValue] = useState(null);
    const [forecastValue, setForecastValue] = useState([]);

    const currentLocation = () => {
        return new Promise((resolve, reject) => {
            navigator.geolocation.getCurrentPosition(
                position => {
                    const latitude = position.coords.latitude;
                    const longitude = position.coords.longitude;
                    resolve({ latitude, longitude });
                },
                error => {
                    reject(error);
                }
            );
        });
    };

    useEffect(() => {
        const getWeather = async () => {
            try {
                const { latitude, longitude } = await currentLocation();

                const responseCurrent = await fetch(
                    `https://api.openweathermap.org/data/2.5/weather?${cityValue ? 'q=' + cityValue : 'lat=' + latitude + '&lon=' + longitude
                    }&appid=${key}&units=metric&lang=KR`,
                );

                const responseForecast = await fetch(
                    `https://api.openweathermap.org/data/2.5/forecast?${cityValue ? 'q=' + cityValue : 'lat=' + latitude + '&lon=' + longitude
                    }&appid=${key}&units=metric&lang=KR`,
                );

                if (!responseCurrent.ok || !responseForecast.ok) {
                    throw new Error('네트워크 응답이 좋지 않습니다.');
                }

                const resultCurrent = await responseCurrent.json();
                const resultForecast = await responseForecast.json();

                const oneDay = 1000 * 60 * 60 * 24;
                const offset = 1000 * 60 * 60 * 9;
                const current = new Date().getTime() + offset;
                const DesiredTime = ' 21:00:00';
                const oneDaysLater = new Date(current + oneDay).toISOString().slice(0, 10) + DesiredTime;
                const twoDaysLater = new Date(current + oneDay * 2).toISOString().slice(0, 10) + DesiredTime;
                const threeDaysLater = new Date(current + oneDay * 3).toISOString().slice(0, 10) + DesiredTime;

                const weatherData = resultForecast.list.filter(item => {
                    return item.dt_txt === oneDaysLater || item.dt_txt === twoDaysLater || item.dt_txt === threeDaysLater;
                });

                setWeatherValue(resultCurrent);
                setForecastValue(weatherData);

                console.log(resultCurrent);
                console.log(weatherData);

            } catch (error) {
                console.error('Error: ', error);
                alert('⚠️ 위치를 받아올 수 없습니다. 잠시만 기다려주세요.');
            }
        };

        getWeather();
    }, [cityValue, key]); // `getWeather` 함수는 내부에서 정의되므로 의존성 배열에 포함될 필요 없음

    return (
        <>
            {weatherValue && (
                <div className='weather-background-img'>
                    <h2>{weatherValue.name}</h2>
                    <img className='main-weather-img'
                        src={`${process.env.PUBLIC_URL}/images/${weatherValue.weather[0].icon}.png`}
                        alt={`${weatherValue.weather[0].description}`}
                    />
                    <h3>
                        {parseInt(weatherValue.main.temp)}°C
                    </h3>
                    <h4>
                        현재 날씨는 <strong>{weatherValue.weather[0].description}</strong> 상태입니다.
                    </h4>
                    <ul>
                        <li>
                            <strong>습도</strong>
                            {weatherValue.main.humidity}
                        </li>
                        <li>
                            <strong>풍속</strong>
                            {weatherValue.wind.speed}
                        </li>
                    </ul>
                </div>
            )}
            {forecastValue.length > 0 && (
                <ul className='forecast-list'>
                    {forecastValue.map((item, index) => (
                        <li className='feature-weather' key={index}>
                            <h3>
                                {new Intl.RelativeTimeFormat("ko", {
                                    localeMatcher: "best fit",
                                    numeric: "always",
                                    style: "long",
                                }).format(index + 1, "day")}
                                <span>{item.dt_txt.slice(5, 10)}</span>
                            </h3>
                            <img
                                src={`${process.env.PUBLIC_URL}/images/${item.weather[0].icon}.png`}
                                alt=''
                            />
                            <h2>{parseInt(item.main.temp)}°C</h2>
                            <span>{item.weather[0].description}</span>
                        </li>
                    ))}
                </ul>
            )}
        </>
    );
};

export default DisplayWeather;

 

본래 styled-components로 css 되어 있던 것을 하나하나 다시 풀어내느라 엄청난 시간을 투자했다.

 

 

본격적으로 css 하는건 다음에. 날씨 api 관련 코드를 찾고 적용하는 데에 오늘 시간을 다썼다.

'FCB2O4' 카테고리의 다른 글

21일차  (0) 2024.08.27
21일차  (0) 2024.08.21
19일차  (0) 2024.08.16
18일차  (0) 2024.08.14
17일차  (0) 2024.08.13