-
Notifications
You must be signed in to change notification settings - Fork 0
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
[3주차 심화 과제] 닮은 동물 찾기 #8
base: week3
Are you sure you want to change the base?
Conversation
const restartPage0 = () => { | ||
setShowPage(0); | ||
setSelectedOptions([]); | ||
}; | ||
|
||
const restartPage1 = () => { | ||
setShowPage(1); | ||
setSelectedOptions([]); | ||
}; |
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 handleOptionSelect = useCallback( | ||
(option) => { | ||
setSelectedOptions((prevOptions) => [...prevOptions, option]); | ||
}, | ||
[setSelectedOptions] | ||
); |
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.
👍👍👍👍👍👍👍
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 ANIMAL_DATA = [ | ||
{ answer: [YES, YES, YES], animal: "강아지", imgUrl: "/img/1.png" }, | ||
{ answer: [YES, YES, NO], animal: "고양이", imgUrl: "/img/2.png" }, | ||
{ answer: [YES, NO, YES], animal: "오랑우탄", imgUrl: "/img/3.png" }, | ||
{ answer: [YES, NO, NO], animal: "쿼카", imgUrl: "./img/4.png" }, | ||
{ answer: [YES, HALF, YES], animal: "토끼", imgUrl: "./img/5.png" }, | ||
{ answer: [YES, HALF, NO], animal: "붕어", imgUrl: "./img/6.png" }, | ||
{ answer: [NO, YES, YES], animal: "팬더", imgUrl: "./img/7.png" }, | ||
{ answer: [NO, YES, NO], animal: "비버", imgUrl: "./img/8.png" }, | ||
{ answer: [NO, NO, YES], animal: "얼룩말", imgUrl: "./img/9.png" }, | ||
{ answer: [NO, NO, NO], animal: "돌고래", imgUrl: "./img/10.png" }, | ||
{ answer: [NO, HALF, YES], animal: "쥐", imgUrl: "./img/11.png" }, | ||
{ answer: [NO, HALF, NO], animal: "미어캣", imgUrl: "./img/12.png" }, | ||
{ answer: [HALF, YES, YES], animal: "용", imgUrl: "./img/13.png" }, | ||
{ answer: [HALF, YES, NO], animal: "기린", imgUrl: "./img/14.png" }, | ||
{ answer: [HALF, NO, YES], animal: "곰", imgUrl: "./img/15.png" }, | ||
{ answer: [HALF, NO, NO], animal: "펭귄", imgUrl: "./img/16.png" }, | ||
{ answer: [HALF, HALF, YES], animal: "사자", imgUrl: "./img/17.png" }, | ||
{ answer: [HALF, HALF, NO], animal: "오리", imgUrl: "./img/18.png" }, | ||
]; |
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.
아 나도 이렇게 배치하는거 참고해서 리팩토링 해야겠다 굳굳!!
전반적으로 엄청 깔끔한 듯???? 나도 리팩토링 미루고 있었는데 너꺼 보니까 얼렁 시작하고 싶어졌다 ㅎㅎ 고생했어 앱잼 얼마 안남았는데 끝까지 화이팅 해보자!! |
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.
언니 그새 넘 성장한 것 같은데,,?! 고생 많았어 끝까지 해내다니 멋있디 ❤
</div> | ||
<ThemeProvider theme={theme}> | ||
<GlobalStyle /> | ||
{RenderPage()} |
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.
컴포넌트니까
{RenderPage()} | |
<RenderPage/> |
얘도 JSX 문법으로 이렇게 가져오면 되겠다!
3주차/FindAnimal/src/App.jsx
Outdated
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 [selectedOptions, setSelectedOptions] = useState([]); | ||
|
||
const startGame = (page) => { | ||
if (page === "page1") { |
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.
이런 "page1" 같은 특정 string값은 상수처리해주면 좋아! 미리 const PAGE1 = "page1"
이런식으로 constants에서 따로 선언해놓고 export 해서 쓰는게 더 좋은 코드 습관이랍니당!
page가 여러개니까 더 구조화해보면 constants 에서
export const PAGE = [ ,"page1", "page2", "page3"];
요렇게 export 해서 PAGE[1]
이런식으로 쓸 수 있겠당
인덱스와 페이지 번호가 헷갈리지 않게 0번째 인덱스는 비워놓았어!
const handleOptionSelect = useCallback( | ||
(option) => { | ||
setSelectedOptions((prevOptions) => [...prevOptions, option]); | ||
}, | ||
[setSelectedOptions] | ||
); |
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.
❤❤❤
[setSelectedOptions] | ||
); | ||
|
||
const totalPages = 5; |
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 totalPages = 5; | |
const TOTAL_PAGES = 5; |
<QuestionBox> | ||
<AnswerButton | ||
answer="응!!" | ||
onClick={() => handleOptionChange("웅!")} | ||
/> | ||
<AnswerButton | ||
answer="아니." | ||
onClick={() => handleOptionChange("아니ㅠ")} | ||
/> | ||
</QuestionBox> |
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.
각 페이지에 보면 QuestionBox랑 AnswerButton처럼 반복되는 구조들이 있는데 요런 애들을 컴포넌트로 만들어서 재사용하면 너무 좋은 구조가 되겠다!
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.
예를 들면 QuestionBox라는 컴포넌트를 components 디렉토리 아래에 만들어서
<QuestionBox> | |
<AnswerButton | |
answer="응!!" | |
onClick={() => handleOptionChange("웅!")} | |
/> | |
<AnswerButton | |
answer="아니." | |
onClick={() => handleOptionChange("아니ㅠ")} | |
/> | |
</QuestionBox> | |
<QuestionBox | |
answer={["웅!", "아니ㅠ"]} | |
handlOptionChange={handlOptionChange} | |
/> |
이렇게 넘겨주고,
const QuestionBox = ({answer, handleOptionChange}) => {
// 여기서 answer을 map 돌려서 AnswerButton을 만드는 방식
}
이런식으로!
const matchingAnimalPic = getMatchingAnimal(selectedOptions).imgUrl; | ||
|
||
return ( | ||
<div> |
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.
스타일링도 없이 단지 최상위 태그가 하나 필요해서 div로 감싸주는 경우 React.Fragment
를 사용할 수 있어! 즉, <>
이렇게 빈 태그를 사용해줘도 된답니당
const handleButton1Click = () => { | ||
setIsButton1Active(true); | ||
setIsButton2Active(false); | ||
}; | ||
|
||
const handleButton2Click = () => { | ||
setIsButton1Active(false); | ||
setIsButton2Active(true); | ||
}; |
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.
이것도 하나의 함수로 만들어보면 좋겠다!
|
||
return ( | ||
<Group> | ||
<div className="question-box"> |
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.
리액트에서 className은 카멜케이스로 작성하는 것이 관행! questionBox
return ( | ||
(progress === 25 || progress === 50 || progress === 75) && ( | ||
<St.Bar progress={progress} /> | ||
) | ||
); | ||
}; | ||
|
||
export default ProgressBar; | ||
|
||
const St = { | ||
Bar: styled.hr` | ||
background-color: ${theme.colors.darkBlue}; | ||
margin: 2rem 0; | ||
border-radius: 0.5rem; | ||
width: ${(props) => props.progress}%; | ||
height: 1.5rem; | ||
`, | ||
}; |
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.
와우 progress Bar를 만들어버렸다니 너무 좋다 ,,
✨ 구현 기능 명세
🌠 심화 과제
theme + Globalstyle 적용
애니메이션
헤더
처음으로
버튼→ 추천 종류 선택 화면일시 해당 버튼이 보이지 않습니다.
→ 처음 추천 종류 선택 화면으로 돌아갑니다.
→ 모든 선택 기록은 리셋됩니다.
[ 취향대로 추천 ]
단계 노출
이전으로 버튼
useReducer
,useMemo
,useCallback
을 사용하여 로직 및 성능을 최적화합니다.💎 PR Point
기본과제까지 했을 때 금잔디원 + 서현이가 해준 코리 바탕으로 리팩토링 및 심화과제를 했습니다~
☘️ 전역 스타일링을 위해 theme + Globalstyle 적용. 또 많이 쓰는 styled 컴포넌트는 commonStyle에서 export해서 사용했습니당.
☘️ 1초를 기준으로 카운트다운하는 숫자에 애니메이션을 적용하였습니다
☘️ 진행바를 만들어서 단계를 시각화하였습니다. 총 페이지와 현재 페이지 숫자가 기준입니다.
☘️ 이전으로/다음으로 버튼 + useCallBack
이전으로 갈때는 마지막으로 배열에 추가된 option을 slice합니다.
다음으로 갈때는 배열에 option을 추가해줍니다.
handleOptionSelect에 useCallBack을 적용해봤습니당
☘️ 중복되는 코드 함수화
🥺 소요 시간, 어려웠던 점
6-7h
🌈 구현 결과물
Screen.Recording.2023-12-12.at.3.06.49.AM.mov