-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ 4주차 기본/심화 과제 ] 4주차 과제 제출 #7
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고했습니당
|
||
const useGetWeatherInfo = (type: string, area: string) => { | ||
const [dailyData, setDailyData] = useState<WeatherInfoProps>(); | ||
const [weeklyData, setWeeklyData] = useState<GetFiveDayWeatherInfoProps>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
props를 확인해봐야하긴 할것 같은데 union type으로 dailyData와 weeklyData를 통합할 수 있을 것 같기두?!
<Suspense> | ||
<Routes> | ||
<Route path="/" element={<MainPage />}> | ||
<Route path="/:type" element={<Error404 error="도시 이름을 입력해주세요!" />} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
진짜 별거 아니구 area는 어떤 값이 올지 몰라서 QueryParam이나 QueryString으로 써도 되는데 보통 type으로 daily와 weekly로만 구분되는 url이면 QueryParam을 사용안하고 /daily 또는 /weekly로 고정 url을 쓰는게 맞는거 같습니다!
type === "weekly" | ||
? `https://api.openweathermap.org/data/2.5/forecast?q=${area}&appid=${import.meta.env.VITE_APP_WEATHER}&units=metric` | ||
: `https://api.openweathermap.org/data/2.5/weather?q=${area}&appid=${import.meta.env.VITE_APP_WEATHER}&units=metric`; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요렇게 type값에 따라서 url 생성한거 좋다!
|
||
interface InfoCardProps { | ||
date: string; | ||
imgUrl?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
선택적 매개변수로 표시해줬구나 👍👍
<select onChange={(e) => setType(e.target.value)}> | ||
<option value='daily'>오늘</option> | ||
<option value="weekly">주간</option> | ||
</select> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
select option button 다 넘 시맨틱해!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
형근이 수고 했엉 ! 타스까지 완벽하당 배워가용 ~!
axios | ||
.get(url) | ||
.then((res) => { | ||
type === "daily" ? setDailyData(res.data) : setWeeklyData(res.data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
조건 처리 해준거 좋당 ! 굿굿
@@ -0,0 +1,15 @@ | |||
import { St } from "../template/InfoCardSection" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 이런식으로 재사용할수 있구낭 배워가용
clouds_all: number; | ||
} | ||
|
||
const InfoCard = ({ date, imgUrl, temp, feels_like, temp_min, temp_max, clouds_all }: InfoCardProps) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구조 분해 할당으로 props 넘겨주는 방법 좋다!
`, | ||
InfoCardWrapper: styled.section` | ||
width: 80vw; | ||
padding-top: 20px; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
padding-top만 px로 지정한 이유는 먼가용 ?!
const [type, setType] = useState<string>('daily'); | ||
|
||
const onClick = () => { | ||
// 나중에 예외처리 합시당 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (area && type) 정도로 예외처리 해줘도 좋을것 같앙 !
} | ||
|
||
const St = { | ||
SearchInputForm: styled.article` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
form이니까 article도 좋지만 form 태그를 사용해도 좋을것 같아!
weather: [ | ||
{ | ||
description: string; // 날씨 설명 | ||
} | ||
]; | ||
main: { | ||
temp: number; // 현재 온도 | ||
feels_like: number; // 체감기온 | ||
temp_min: number; // 최저 | ||
temp_max: number; // 최고 | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
주석까지 넘 깔끔합니당!
export const getMonthDate = () => { | ||
const getDate = new Date(); | ||
const nowMonth = getDate.getMonth() < 10 ? "0" + (getDate.getMonth() + 1) : getDate.getMonth() + 1; | ||
const nowDate = getDate.getDate() < 10 ? "0" + getDate.getDate() : getDate.getDate(); | ||
return `${nowMonth}-${nowDate}`; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
date 값을 이렇게 만들어줘도 좋지만 daily data에 있는 값을 가져와서 써도 좋을것 같아!
✨ 구현 기능 명세
기본 과제
✅
기상 카드
=> 구현 완료했습니다!
✅
일간 / 주간 + 지역(영어)검색
=> useParams를 활용해 렌더링하도록 구현했습니다!
✅
Outlet + Route
=> 구현 완료했습니다! 에러 페이지 처리 완료했습니다! 추가적으로 라우터 단위에서 에러 페이지를 표시하도록 했습니다.
심화 과제
✅
스켈레톤 UI
=> 구현하고 Shimmer 이펙트 적용했습니다!
✅
커스텀훅으로 데이터를 받아옵시다!
=> 커스텀 훅 구현하였습니다!
🌼 PR Point
커스텀 훅
src/api/hooks/weatherInfo.ts
커스텀 훅을 구현하여 훅 내부에서 비동기 함수의 실행 상태에 따라 data, loading, error 를 표시해줄 수 있도록 하였습니다.
추가적으로 비동기 함수에 useCallback을 적용하여 url이 바뀌는 경우에만 함수를 리프레쉬하도록 해주었습니다.
예외처리
src/components/atom/Error404.tsx
기본적인 에러 표시 컴포넌트를 만든 뒤,
src/components/template/InfoCardSection.tsx
맨 마지막에 데이터가 존재하지 않는 경우 에러를 반환하도록 해주었습니다.
src/pages/Router.tsx
이때 인풋 값에 아무것도 없는 경우를 처리해주기 위해
라우터 단에서 만일 area정보가 없는 상태로 라우팅이 되면 에러 컴포넌트가 반환되도록 해주었습니다.
현재 도시를 나타내도록 레이아웃 재구성
src/components/template/InfoCardSectin.tsx
일간 / 주간 관계없이 사용자가 검색한 현재 위치를 표시해주도록 '현재 도시' 를 따로 정의하여 넣어주었습니다!
렌더링 최적화
src/components/organism/InfoCard.tsx
앞서 언급한 useCallback과 더불어 props에 동일한 데이터가 내려오는 경우 InfoCard의 리렌더링이 발생하지 않도록 메모이제이션 해주었습니다.
Fallback shimmer 적용
src/components/atom/Shimmer.tsx
높이와 너비를 입력받는 쉬머 스켈레톤 컴포넌트를 만들었고,
src/components/template/InfoCardSection.tsx
Loading 중일 때 각 상황에 맞는 쉬머 컴포넌트를 렌더링하도록 해주었습니다.
🥺 소요 시간, 어려웠던 점
8h
파트장님 짱~
🌈 구현 결과물
☀️웨비들의 기상예보☀️