Skip to content

Commit

Permalink
[Fix] 날씨 Provider 구현 완료 PerformanceImprove #82
Browse files Browse the repository at this point in the history
  • Loading branch information
nebulaBdj committed Apr 2, 2024
1 parent 98e3f91 commit cfd3179
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 191 deletions.
68 changes: 49 additions & 19 deletions weatherfit_refactoring/contexts/WeatherContext.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
'use client'
import { ReactNode, createContext, useEffect, useState } from 'react'

type WeatherType =
| 'Clear'
| 'Rain'
| 'Thunderstorm'
| 'Snow'
| 'Mist'
| 'Drizzle'
| 'Clouds'
| 'Fog'
| 'Haze'
| 'Sand'
interface WeatherProvider {
icon: string | undefined
tempNow: number | undefined
tempMax: number | undefined
tempMin: number | undefined
icon: string | null
tempNow: number | null
tempMax: number | null
tempMin: number | null
address: string | null
weather: WeatherType | null
}

export const WeatherContext = createContext<WeatherProvider | undefined>(
undefined,
)
export const WeatherContext = createContext<WeatherProvider>({
icon: null,
tempMax: null,
tempMin: null,
tempNow: null,
address: null,
weather: null,
})

export const WeatherProvider = ({ children }: { children: ReactNode }) => {
const [temperature, setTemp] = useState<number>()
Expand All @@ -19,7 +37,8 @@ export const WeatherProvider = ({ children }: { children: ReactNode }) => {
const [weatherIcon, setIcon] = useState<string>()
const [latitude_state, setLatitude] = useState<number>()
const [longitude_state, setLongitude] = useState<number>()
const [address, setAddress] = useState<string | undefined>()
const [address, setAddress] = useState<string>()
const [weather, setWeather] = useState<WeatherType>()

// API Keys
// openweathermap
Expand Down Expand Up @@ -50,7 +69,6 @@ export const WeatherProvider = ({ children }: { children: ReactNode }) => {

useEffect(() => {
const getWeather = async () => {
console.log('위도', latitude_state, '경도', longitude_state)
try {
// OpenWeatherMap에서 위치 기반 날씨 정보 불러오기
const weatherResponse = await fetch(
Expand All @@ -60,6 +78,7 @@ export const WeatherProvider = ({ children }: { children: ReactNode }) => {

// 날씨 정보 저장하기
setIcon(weatherData.weather[0].icon)
setWeather(weatherData.weather[0].main)
setTemp(weatherData.main.temp.toFixed(1))
setTempMax(weatherData.main.temp_max.toFixed(1))
setTempMin(weatherData.main.temp_min.toFixed(1))
Expand Down Expand Up @@ -92,18 +111,29 @@ export const WeatherProvider = ({ children }: { children: ReactNode }) => {
}
}

if (address) getAddress()
getAddress()
}, [temperatureMin])

return (
<WeatherContext.Provider
value={{
icon: weatherIcon,
tempMax: temperatureMax,
tempMin: temperatureMin,
tempNow: temperature,
}}>
{children}
</WeatherContext.Provider>
<>
{weatherIcon &&
temperature &&
temperatureMax &&
weather &&
temperatureMin &&
address && (
<WeatherContext.Provider
value={{
icon: weatherIcon,
weather: weather,
address: address,
tempMax: temperatureMax,
tempMin: temperatureMin,
tempNow: temperature,
}}>
{children}
</WeatherContext.Provider>
)}
</>
)
}
102 changes: 7 additions & 95 deletions weatherfit_refactoring/src/Components/Molecules/WeatherNavbar.tsx
Original file line number Diff line number Diff line change
@@ -1,114 +1,26 @@
'use client'
import { useEffect, useState } from 'react'
import { useContext, useEffect, useState } from 'react'
import Image from 'next/image'
//Zustand
import { WeatherIcon } from '@/Store/WeatherIcon'
import { WeatherTemp } from '@/Store/WeatherTemp'
import { WeatherTempMax } from '@/Store/WeatherMaxTemp'
import { WeatherTempMin } from '@/Store/WeatherMinTemp'
import { WeatherContext } from '../../../contexts/WeatherContext'

export default function WeatherNavbar() {
// const API_KEY = 'fa3eba61f243af3e8e69086462763172'
const API_KEY = 'e88170b7fa2aeadd4ba37bb1561a53f2'
const KAKAO_API_KEY = '3a6c3035c801405eaa71ebb9dc7f474b'

const { temperature, setTemp } = WeatherTemp()
const { temperatureMin, setTempMin } = WeatherTempMin()
const { temperatureMax, setTempMax } = WeatherTempMax()
const { weatherIcon, setIcon } = WeatherIcon()
const [latitude_state, setLatitude] = useState<number>()
const [longitude_state, setLongitude] = useState<number>()
const [address, setAddress] = useState<string | undefined>()

// 렌더링 속도 비교해보기

useEffect(() => {
const getLocation = async () => {
try {
// 위치 노출이 허용되어 있는지 확인하고 현재 위치 가져오기
const position = await new Promise<GeolocationPosition>(
(resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject)
},
)

// 위도와 경도 가져오기
setLatitude(position.coords.latitude)
setLongitude(position.coords.longitude)
} catch (error) {
console.error('Error getting location:', error)
}
}

getLocation()
}, [])

useEffect(() => {
const getWeather = async () => {
console.log('위도', latitude_state, '경도', longitude_state)
try {
// OpenWeatherMap에서 위치 기반 날씨 정보 불러오기
const weatherResponse = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${latitude_state}&lon=${longitude_state}&appid=${API_KEY}&units=metric`,
)
const weatherData = await weatherResponse.json()

// 날씨 정보 저장하기
setIcon(weatherData.weather[0].icon)
setTemp(weatherData.main.temp.toFixed(1))
setTempMax(weatherData.main.temp_max.toFixed(1))
setTempMin(weatherData.main.temp_min.toFixed(1))
} catch (error) {
console.error('Error getting location:', error)
}
}

if (latitude_state && longitude_state) getWeather()
}, [latitude_state, longitude_state])

useEffect(() => {
const getAddress = async () => {
try {
const addressResponse = await fetch(
`https://dapi.kakao.com/v2/local/geo/coord2address.json?x=${longitude_state}&y=${latitude_state}`,
{
method: 'GET',
headers: { Authorization: `KakaoAK ${KAKAO_API_KEY}` },
},
)
const addressData = await addressResponse.json()
setAddress(
addressData.documents[0].address.region_1depth_name +
' ' +
addressData.documents[0].address.region_2depth_name,
)
} catch (error) {
console.error('Error getting location:', error)
}
}

if (address) getAddress()
}, [temperatureMin])
const { icon, tempMax, tempMin, tempNow } = useContext(WeatherContext)

return (
<article className="flex justify-between items-center text-[12px] border-t border-b border-slate-100 px-2">
<section className="flex items-center">
<Image
src={`https://openweathermap.org/img/wn/${weatherIcon}.png`}
src={`https://openweathermap.org/img/wn/${icon}.png`}
alt="weatherIcon"
width={50}
height={50}
loading="lazy"
/>
<span className="font-gmarketsans font-thin pt-1">{temperature}</span>
<span className="font-gmarketsans font-thin pt-1">{tempNow}</span>
</section>
<section className="px-1">
<span className="font-gmarketsans font-thin px-1">
최고 {temperatureMax}
</span>
<span className="font-gmarketsans font-thin px-1">
최저 {temperatureMin}
</span>
<span className="font-gmarketsans font-thin px-1">최고 {tempMax}</span>
<span className="font-gmarketsans font-thin px-1">최저 {tempMin}</span>
</section>
</article>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import Image from 'next/image'
import { WeatherIcon } from '@/Store/WeatherIcon'
import { WeatherContext } from '../../../../contexts/WeatherContext'
import { useContext } from 'react'

export default function Weather({
initialWeatherIcon,
}: {
initialWeatherIcon?: FEEDDATA_detail['weatherIcon']
}) {
const { weatherIcon } = WeatherIcon()
const { icon } = useContext(WeatherContext)
return (
<div className="flex mb-3 items-center w-fit">
<p className="font-gmarketsans pt-[5px] mr-3 text-sm">
Expand All @@ -16,7 +17,7 @@ export default function Weather({
src={
initialWeatherIcon
? initialWeatherIcon
: `https://openweathermap.org/img/wn/${weatherIcon}.png`
: `https://openweathermap.org/img/wn/${icon}.png`
}
alt="날씨"
width={20}
Expand Down
Loading

0 comments on commit cfd3179

Please sign in to comment.