Skip to content
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주차 기본/심화/생각 과제] 🎅크리스마스에 뭐 할래?🎄 #3

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

aazkgh
Copy link
Member

@aazkgh aazkgh commented Nov 10, 2023

🌱 기본 조건

  • 기본조건1

✅ 선택 과정은 총 3단계입니다. ( 3개 → 3개 → 2개)

✅ 아이템은 총 18개 이상입니다. (3 x 3 x 2 = 18)

위는 “최소”기준이며 그 이상의 개수는 가능합니다.

  • 기본조건2

✅ 전역상태관리 라이브러리, context 사용 금지 ❌

✅ Router 사용 금지 ❌


🧩 기본 과제

  1. 추천 종류 선택
    • 취향대로 추천 / 랜덤 추천 중 선택합니다.
    • 선택시 다음화면으로 넘어갑니다.

[취향대로 추천]

  1. 답변 선택

    • 호버시 스타일 변화가 있습니다.
    • 클릭시(선택시) 스타일 변화가 있습니다.
  2. 이전으로, 다음으로(결과보기) 버튼

    • 아무것도 선택되지 않았을 시 버튼을 비활성화 시킵니다.

      → 눌러도 아무 동작 X

      → 비활성화일 때 스타일을 다르게 처리합니다.

    • 이전으로 버튼을 누르면 이전 단계로 이동합니다.

    • 다음으로 / 결과보기 버튼을 누르면 다음 단계로 이동합니다.

    • 버튼 호버시 스타일 변화가 있습니다.

  3. 결과

    • 선택한 정보들에 맞는 결과를 보여줍니다.

[ 랜덤 추천 ]

  1. 숫자 카운트 다운
    • 3 → 2 → 1 숫자 카운트 다운 후 결과를 보여줍니다.
    • 추천 결과는 반드시 랜덤으로 지정합니다.

[ 공통 ]

  1. 결과 화면
    • 다시하기 버튼

      → 랜덤추천이면 랜덤 추천 start 화면으로, 취향대로 추천이면 취향대로 추천 start 화면으로 돌아갑니다.

      → 모든 선택 기록은 리셋됩니다.


🌠 심화 과제

  1. theme + Globalstyle 적용

    • 전역으로 스타일을 사용할 수 있도록 적용해보세요
  2. 애니메이션

    • 랜덤 추천 - 카운트다운에 효과를 넣어서 더 다채롭게 만들어주세요!
  3. 헤더

    • 처음으로 버튼

      → 추천 종류 선택 화면일시 해당 버튼이 보이지 않습니다.

      → 처음 추천 종류 선택 화면으로 돌아갑니다.

      → 모든 선택 기록은 리셋됩니다.

[ 취향대로 추천 ]

  1. 단계 노출

    • 3단계의 진행 단계를 보여줍니다.
  2. 이전으로 버튼

    • 이전으로 돌아가도 선택했던 항목이 선택되어 있습니다.
  • 6. useReducer , useMemo , useCallback 을 사용하여 로직 및 성능을 최적화합니다.

생각과제

  • 리액트에 대하여
  • 컴포넌트는 어떤 기준과 방법으로 분리하는 것이 좋을까?
  • 좋은 상태 관리란 무엇일까?
  • 렌더링을 효과적으로 관리하는 방법은 무엇이 있을까?
  • Props Drilling이란 무엇이고 이를 어떻게 해결할 수 있는가?

💎 PR Point

컴포넌트 재활용성에 집중해서 코드를 짰는데
오히려 컴포넌트의 가독성이 과하게 떨어지는 방향이 된 것 같아서,,,
다음엔 둘 다 챙기려고 노력하려고요,,,리팩토링 했는데도 여기가 (지금은) 저의 한계인 듯 합니다

✔ reducer 함수를 이용해서 여러 state

  • count -> 라운드 수 / indexList -> 선택한 결과값 / active -> 버튼 활성화
  • 이전으로 / 다음으로 / 선택지 선택 -> 3가지 상황을 reducer 하나로 다뤘어용 (애증의 reducer)
  • 정말정말 힘들었지만 reducer에 대해 꽤나 알게 된 기분임니다
function reducer(state, action){
    switch (action.type){
        case "previous":
                state.indexList.pop();
            return { count: state.count - 1,
                    indexList: state.indexList,
                    active: true };        
        case "next":
            state.indexList.push("");
            return { count: state.count + 1, 
                    indexList: state.indexList, 
                    active: false };
        case "select":
            state.indexList.splice(state.indexList.length-1, 1, action.answer)
            return { count: state.count,
                    indexList: state.indexList, 
                    active: true };
    };
}

    const [page, dispatch] = useReducer(reducer, { count: 0, indexList: [], active: false});

useEffect()를 사용해서 렌더링 (dispatch 함수를 props로 전달해서 해결)

  • 이번 코드에서 제가 미치도록 마음에 안 드는 부분입니다,,, (그래서 과제 제출 후 밤새서 리팩토링 완료)
  • list state를 사용하는 list 컴포넌트와 next state를 사용하는 next 컴포넌트를 별도로 분리해주려고 했는데 처참히 실패했습니다.
  • 두 컴포넌트 다 reducer 함수를 사용하는 page state를 업데이트 해주는 기능을 갖고 있기 때문에ㅜ
  • 나중에 전역 관리 어쩌구(context)를 배우는 걸로 아는데 그걸 사용하면 좀 낫지 않을까 싶어용
useEffect(() => {
        switch (page.count) {
            case 0:
                setList(["취향대로 추천"]);
                setNext("시작!");
                break;
            case 1:
                setList(["가족들이랑 놀래", "친구들이나 애인이랑 놀래", "웨비들💛이랑 놀래"]);
                setNext("다음으로");
                break;
            case 2:
                setList(["맛있는 거 먹기", "크리스마스 분위기 느끼기", "신나게 놀기"]);
                setNext("다음으로");
                break;
            case 3:
                setList(["실내가 좋아", "실외가 좋아"]);
                setNext("결과보기");
                break;
        }   
    }, [page.count]);

theme를 사용해서 스타일링

  • styled-component 요소들은 별도 파일(style 디렉토리 내부)로 분리해줬습니다!
  • reset.css는 GlobalStyle 내부에 만들어줬어요
  • theme으로 color랑 중요도 순서로 font를 다르게 주었어요!
import { css } from "styled-components";

const colors = {
    green: "#2c5530",
    red: "#b60017",
    darkRed: "#52000a",
    white: "#faf8f8",
    beige: "#f2e8cf"
};

const fonts = {
    title: css`
      font-family: Bagel Fat One;
      font-size: 2.5rem;
      font-weight: 500;
    `,
    subtitle: css`
      font-family: Orbit;
      font-size: 1.6rem;
      font-weight: 600;
    `,
    content: css`
      font-family: Orbit;
      font-size: 1rem;
      font-weight: 500;
    `,
  };

const theme = {
    colors, fonts
};

export default theme;

🥺 소요 시간, 어려웠던 점

🗨 20h~25h 정도

  • 리액트를 아예 처음 하는 입장에서 처음에 어떻게 시작해야 될 지도 몰라서 감을 잡느라 오래 걸렸어요ㅜ

  • 초반에 컴포넌트를 많이 만들면 안 된다는 강박?에 빠져서 토너먼트 스테이지를 한 컴포넌트에 다 만든 게 패착이라면 패착,,?

  • 컴포넌트 재사용성을 높이려고 하다가 가독성이 떨어진 것 같아요ㅜ 2개 다 챙기는 건 넘 어려운 것 같다는!!

  • 얽히고 설킨 state가 많아서 보시는 게 조금 힘들 것 같긴 한데,,,그래도 코리 잘 부탁드려용❤

  • 마지막 리팩토링을 도와준 짱뜽희와 션언니에게 깊은 감사를 표합니다(´▽`ʃ♡ƪ)


🌈 구현 결과물

https://drive.google.com/drive/folders/1ogE0DxRlAt5JruaB8SPOiE9_YEgFIBz6?usp=sharing

@aazkgh aazkgh self-assigned this Nov 10, 2023
@aazkgh aazkgh changed the title [3주차 과제] 🎅크리스마스에 뭐 할래?🎄 [3주차 기본/심화/생각 과제] 🎅크리스마스에 뭐 할래?🎄 Nov 10, 2023
Copy link

@lydiacho lydiacho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드의 일부를 같이 고민해본 기념으로(?) 코드리뷰 하러 놀러왔습니다 😎 (숭이의 첫 잔디 밖 리뷰)
보면서 깜짝 놀랐던게 리액트를 처음 사용해본다고 했는데, 심화적인 내용도 너무 잘 공부하고 적용했고(useReducer 같은), 특히 조건부 렌더링을 진짜 잘 활용하네요 🫢 대체 얼마나 열심히 하는거냐고 ~

수고 너무너무 많았고 코멘트 내용 이해가 안간다면 언제든 질문 환영입니당

Comment on lines +28 to +36
<Stage>
<Question>원하는 추천 방식을 골라줘!</Question>
<ChoiceBoxWrapper>
<ChoiceBox>
랜덤으로 추천
</ChoiceBox>
</ChoiceBoxWrapper>
<Button onClick={() => {setStart(true)}}>시작!</Button>
</Stage>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요 부분은 App.jsx에서 default 경우의 렌더링과 거의 동일한 레이아웃이기 때문에 반복해서 사용하기보다는 컴포넌트 분리 해서 재사용해봐도 좋을 것 같아요!!!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나두 숭이 말한거처럼 바깥 틀이 비슷한 경우라 안에껏만 갈아끼워주는 방식으로 리팩해주면 좋을거 같단 생각!

Comment on lines +7 to +21
function CountDown() {
function Timer(){
const [time, setTime] = useState(3);

useEffect(() => {
time > 0 && setTimeout(() => setTime(time - 1), 1000);
}, [time]);

return time
? <Stage><NumEffect>{time}</NumEffect></Stage>
: <RandomResult></RandomResult> ;
}

return (<>{Timer()}</>);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CountDown 컴포넌트가 하고 있는 역할이

  • Timer 컴포넌트 생성
  • Timer 컴포넌트 반환(렌더링)

밖에 없기 때문에, CountDown과 Timer는 불필요하게 중첩되진 않았는지 고민해보면 좋을 것 같아요!!

즉, 아래와 같이 Timer를 새로운 함수로 정의해주지 않아도 충분히 표현이 가능하겠죠??

Suggested change
function CountDown() {
function Timer(){
const [time, setTime] = useState(3);
useEffect(() => {
time > 0 && setTimeout(() => setTime(time - 1), 1000);
}, [time]);
return time
? <Stage><NumEffect>{time}</NumEffect></Stage>
: <RandomResult></RandomResult> ;
}
return (<>{Timer()}</>);
}
function CountDown() {
const [time, setTime] = useState(3);
useEffect(() => {
time > 0 && setTimeout(() => setTime(time - 1), 1000);
}, [time]);
return time
? <Stage><NumEffect>{time}</NumEffect></Stage>
: <RandomResult></RandomResult> ;
}

또 Stage 컴포넌트를 여기서 사용하는 것이 맞나! 고민해봐도 좋을 것 같아요!
Stage 컴포넌트가 어딘가에서 재사용되기 때문에 index 파일로 분리시킨 것일 텐데,
다른 곳에서 Stage 컴포넌트가 보여지는 스타일과, 이곳에서 time 숫자가 보여지는 스타일이 연관성이 전혀 없다면
아무리 CSS 코드가 동일한 부분이 있더라도, 같은 모듈로 묶어주지 않는 것이 좋을 수도 있어요!

말이 어려울 수 있는데, 쉽게 말하면 이곳은 stage 즉 단계를 보여주는 것과 무관한 랜덤 추천 타이머를 보여주는 부분이기 때문에 단계를 보여주는 역할의 컴포넌트가 재사용되기에는 찰떡의 자리는 아닐 수 있다! 라는 의견도 한번 남겨봅니당

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말 어렵지 않았구 완전 이해했습니다❤❤❤ 승희 말대로 CSS가 동일해서 그렇게 쓴 건데 굳이 이렇게 안 써줘도 되는 부분이었던 것 같아요!! 친절한 조언 완전 감사랑합니다❤

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

숭희 피드백 완전 좋다..... 유익해.....

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tournamant flow와 연관된 컴포넌트들의 파일명을 tournament-{컴포넌트} 식으로 네이밍 해주었는데요! 요것도 좋은 방법이지만 components 디렉토리 내부에 tournament 디렉토리를 하나 더 만들어서 그 안에 button.jsx, content.jsx ... 이렇게 넣어주면 더 깔끔하게 파일명 및 경로를 관리할 수 있겠죠?!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

왕 감사합니당!! 디렉토리 활용을 좀 더 해볼게요!!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전에 프로젝트 하면서도 생각 못 해봤던 방법인데 완전 좋다.....!! 코리 진짜 너무 유익해,,,,,

Comment on lines +11 to +12
const tempInfo = RESULT_LIST[randomVal];
const {link, description , ...indexs} = tempInfo;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const tempInfo = RESULT_LIST[randomVal];
const {link, description , ...indexs} = tempInfo;
const {link, description , ...indexs} = RESULT_LIST[randomVal];

tempInfo라는 아주잠깐! 사용되는 변수에 메모리 자원을 할당하는 것보다, 이렇게 바로 할당해주는게 더 좋겠죠?!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이친구는 images 디렉토리 밖으로 삐져나와있네요!! 사소한 점이지만 이럴 경우 나중에 경로를 통해 이미지를 찾는 과정에서 혼동될 수 있기 때문에 이런 부분도 세심히 챙겨주면 미래의 나에게 아주아주 큰 도움이 됩니다 크크

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

theme을 아주 야무지게 잘 썼네용!! 현재 theme 파일을 assets 디렉토리 내부에 넣어주었는데, 일반적으로는 assets가 아닌 styles 디렉토리 내부에 GlobalStyle 파일과 같이 위치시켜주곤 합니다!
사실 디렉토리 구조는 내가 짜는 나름이 아닌가~ 할 수 있지만 앞으로 우리는 합세, 솝커톤, 앱잼 등등 수많은 협업을 해나갈거기 때문에 이런 관습적인 부분도 최대한 지켜주는 것이 좋답니다 😎 (그런걸 컨벤션이라고 부르지요! 모든 프로젝트에 앞서 필수적으로 팀원들 간에 협의해서 정하는 내용입니다)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

궁금한 것이 있습니당!! 그러면 요런 theme 파일처럼 보통 GlobalStyle 파일도 분리해서 작성하는 걸 권장하시나요??!!?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네!! 저도 그러는 편이고, 대부분의 react 프로젝트에서 style 관련 디렉토리theme 파일과 GlobalStyle 파일을 분리해서 위치시켜줍니당
그 이유는, 다른 스타일드 컴포넌트는 각각 종속된, 즉 매칭되는 타겟 컴포넌트를 스타일링해주기 위한 코드이고, GlobalStyle은 프로젝트 전반에 공통적으로 적용시켜주는 스타일이기 때문에 목적, 기능이 달라서 분리시켜주면 좋습니다 :)

우리가 컴포넌트를 분리해줄 때, 각 화면을 보여주는 컴포넌트와 별개로 여러 UI에 공통으로 사용되는 컴포넌트를 분리시켜주는 것과 동일한 맥락이라고 이해하면 쉽겠네용!! 👍

<Button onClick={ () => {setInitial(true)} }>다시하기</Button>
</Stage>
)
: <Random></Random>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 내용물이 비어있는 열림/닫힘 태그를 이곳저곳에서 많이 사용해주었는데, 내부 children이 없는 대부분의 컴포넌트는 주로 단일태그를 사용한답니다 !

Suggested change
: <Random></Random>;
: <Random />;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 그렇군뇨! 사실 자동완성이 항상 저렇게 되길래 아무 생각 없이 썼는데 새로운 걸 알아갑니다❤
혹시 저렇게 단일 태그를 자동완성 시켜주는 별도의 extension이 있나요? 아님 제가 하나씩 쳐야되는 걸까요?? (물론, 후자가 아닐 거라고 생각은 합니다,,,)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 항상 직접 작성해주곤 했었는데 가형이 코멘트 보고 찾아보니까 eslint-plugin-react에 self-closing-comp 라는 rule이 존재하네요!!! 대박대박 저도 몰랐는데 이거 꼭 써봐야겠어요
self-closing-comp rule

자료 참고하고, 앞으로 우리에게 닥칠 합세, 솝커톤, 앱잼에서 조원들과 컨벤션을 정하는 시간에 eslint 규칙도 정하게 될텐데, 그때 적용하자고 가형이가 의견 내보면 아주아주 좋을듯 !! ❤️

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

참고로 얘는 셀프 클로징 태그 라고도 불러용-!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

global style 설정 파일을 style 디렉토리에 아주 잘 넣어주었네요 !! 여기서 파일명까지 GlobalStyles 이런식으로 조금만 더 직관적으로 설정해준다면 ! 더 원활한 협업이 가능해지겠쥬?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 아직 파일명이나 디렉토리명을 어떻게 지어야될 지 좀 낯선데 친절하게 예시까지 들어줘서 감사합니다❤

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가로 theme이나 GlobalStyles 파일은 .jsx 가 아닌 .js파일로 만들어주는 경우가 많은데,
js파일이 jsx보다 작고 로딩이 빨라서 글로벌 스타일이 많으면 많을수록 성능상 유리해지기 때문이래용-!

아무래도 jsx는 babel을 거쳐 한 번 컴파일이 되야하니까 그런듯,,!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전역 스타일 파일은 js로 해주는 이유가 궁금했는데 성능상의 이유가 있었군용...!!

state.indexList.splice(state.indexList.length-1, 1, action.answer)
return { count: state.count,
indexList: state.indexList,
active: true };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 트러블슈팅 때 이부분을 지나가면서 보고 active을 어떻게 사용하고 있는건지 더 살펴보고 싶어서 코드리뷰를 왔던건데요 크크크
제 유추가 맞다면 가형이는 각 버튼의 활성화 여부를 관리하고자 state에 active를 담아서 함께 관리해주는 것 같아요!
그런데 버튼의 활성화 여부는 사용자가 선택지를 선택했는가 or 이전/다음단계가 없는가조건, 상황에 따라 부여해주는거잖아요!

그래서 이렇게 각 값을 정적으로 박아넣기 보다, active 값이 필요한 곳에서 indexList의 현재 단계 index에 값이 들어와있는가? 빈문자열인가? 에 따른 true/false를 입력해주는 등의 방식을 사용해주는건 어떨까요!!

특히, 제가 코드를 살펴본 바로는 (어딘가 놓쳤을 수도 있지만) active 속성의 값을 사용하는 곳이 결과보기/다음으로 버튼의 disabled 여부를 결정하는 데에만 사용되고 있는 것 같아요! 만약 이게 맞다면 더더욱 state 객체 내의 프로퍼티로 active 값을 이리저리 데리고 다니기 보다 그 부분에서만 위에서 말한대로 버튼이 비활성화되는 조건을 명시해두는 방법을 조심스레 제안해봅니당 😚

P.S.
이번 과제에서 스타일 컴포넌트에 props를 넘겨줘서 스타일을 동적으로 적용시키는 방식을 아직 사용해보지 않은 것 같아요!
요번 과제는 해당 내용을 실습해보기 딱 좋은 과제라고 생각하기 때문에 리팩토링할 때 한번 사용해봐도 좋을 것 같아요:)
터혀니의 동적 스타일링 셈나 자료 다시보기
숭이의 동적 스타일링 적용 보러가기

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

승희가 놓친 것 없구 제 로직을 정확히 파악한 게 맞습니다 크크

사실 원래는 다루고 있는 state가 여섯 개? 정도 됐는데 리팩토링 하면서 1개로 줄였거든요 ㅋㅎㅋㅎ
이 정도면 충분히 줄였다고 생각했는데 active 값도 굳이 필수적으로 줘야할 건 아닌 것 같네요! indexList를 이용해서 충분히 활용 가능할 것 같습니다.

P.S.에서 승희가 말한대로 제가 props 넘기는 방법도 몰라서 이번에 물어물어 해본 건데 동적 스타일링 가능하다는 것도 승희가 말해줘서 처음 알았습니다❤ 코리 반영하면서 한 번 실습해볼게요!! YB의 성장까지 챙겨줘서 짱짱짱 감사합니다 ㅎㅎㅎ 친절한 코리 완전 감동이에요(❁´◡`❁)

Copy link

@SynthiaLee SynthiaLee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것이 우수과제상 수상 왕초보아닌 노빠꾸 고가형의 코드다.👏🏼

<ChoiceBox type="button"
onClick={() => {setCurrentStage("tournament");}}>
취향대로 추천
</ChoiceBox>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요기 컴포넌트 재사용 해준거 아주 굿-!

}
};

const resetBtn = () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함수명을 지을 때는 이 함수가 어떤 일을 하는지 한번에 알기쉽게 동사형태로 짓는 걸 추천해-!
resetBtn 같은 명사는 컴포넌트 이름으로 사용하는 경우가 더 많으니까~
요거 같은 경우엔 renderResetBtn 같은 이름으로 함수명 지어주면 좋을듯~..

  • 개인적으로 난 동사형태로 함수명을 짓다보면 한 함수에 자꾸 이것저것 기능을 추가하는 일도 좀 줄어들더라고!!
    딱 이름에 맞는 기능만 넣어주게 되는???

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 진짜 공감!!! 나도 요즘 동사형태로 함수명 짓는 습관 들이고 있는데 가독성도 좋고 직관적이라 좋더라구 :)

<Button onClick={ () => {setInitial(true)} }>다시하기</Button>
</Stage>
)
: <Random></Random>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

참고로 얘는 셀프 클로징 태그 라고도 불러용-!

import { useState } from "react";

function RandomResult(){
const [initial, setInitial] = useState(false);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요오것은 약간 영어관련이긴한데 Initial은 형용사라서 (명사로 쓰엿다해도 그 이름의 첫글자라는 뜻이라) 뒤에 stage라던지 무언가 명사를 추가해주는게 이해가 더 쉬울거 같오!!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

역시 시연스쿨✨ 깨알 영어지식 줍줍.....

?(
<Stage>
<Question>크리스마스에 이거 하면 되겠다!</Question>
<AnswerImg src={link}></AnswerImg>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 img 태그니까 alt 도 잊지말구 넣어줍시댱~!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가로 theme이나 GlobalStyles 파일은 .jsx 가 아닌 .js파일로 만들어주는 경우가 많은데,
js파일이 jsx보다 작고 로딩이 빨라서 글로벌 스타일이 많으면 많을수록 성능상 유리해지기 때문이래용-!

아무래도 jsx는 babel을 거쳐 한 번 컴파일이 되야하니까 그런듯,,!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와 스타일드 컴포넌트를 따로 빼서 가져다 쓰는건 처음봤는데 같은 구조에서 반복적으로 사용되는게 많으면 좋을 수도 있겠다,,,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나도 이렇게 쓸 수 있다는 거 처음 알았엌ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 나두 나중에 써먹어봐야지!!!!! :)

<Question>크리스마스에 이거 하면 되겠다!</Question>
<AnswerImg src={link}></AnswerImg>
<Answer>🌟{description}❄️</Answer>
<Button onClick={ () => {setInitial(true)} }>다시하기</Button>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

button 태그니까 type='button'도 잊지말고 넣어줍시댱~

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

누나가 항상 버튼 태그에 type="button" 넣어주길래 왜지...? 싶었는데 이번에 궁금해서 찾아봤거든!!
https://nykim.work/96
처음 알았어..... 이렇게 오늘도 또 새로운 걸 알게 되었따 😌

이전으로
</MoveButton>
<MoveButton onClick={() => {dispatch({ type: "next" })}}
disabled={!active}>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 이거 이렇게 되는구나,,!!
내꺼 리팩때도 적용해줘야지~

border-radius: 0.3rem;
`;

export const MoveButton = styled(Button)`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넘넘굿굿

Copy link
Member

@jungwoo3490 jungwoo3490 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OB들 코리 보고 진짜 많이 배워가는 것 같아..... 코드를 너무 멋대로 짜고 있었다는 생각이 드네...
가형이 코드 보고도 진짜 많이 배워가!! 나도 코드에서 뭔가 재사용성을 늘릴 포인트가 많았는데 리액트 장점을 많이 활용 못 했다는 생각이 들어서 아쉽다 너무.....
명예의 전당 너무 축하하고 과제하느라 고생했어!!!!!! 담주도 홧팅홧팅 🔥

}
};

const resetBtn = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 진짜 공감!!! 나도 요즘 동사형태로 함수명 짓는 습관 들이고 있는데 가독성도 좋고 직관적이라 좋더라구 :)

@@ -0,0 +1,128 @@
export const RESULT_LIST = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수파일 빼둔거 넘 좋다!!!
요런 상수 데이터 파일은 보통 assets 디렉터리가 아니라 constants 디렉터리에서 관리하더라구!! (나도 모르고 utils 디렉토리에 넣긴 했는데...)
밑에 승희 코멘트대로 협업을 하게 되면 뭔가 통용되는 관습같은 컨벤션들을 지켜주는 게 서로 편할 것 같다는 생각이 들어서!!
요거 참고해보면 좋을 것 같아!!
https://velog.io/@sisofiy626/React-%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%9D%98-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0

colors, fonts
};

export default theme;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나두 다음에 theme 적용해봐야겠다..... 가독성도 좋고 너무 편해보여,,,,,,

import { useState } from "react";

function RandomResult(){
const [initial, setInitial] = useState(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

역시 시연스쿨✨ 깨알 영어지식 줍줍.....

<Question>크리스마스에 이거 하면 되겠다!</Question>
<AnswerImg src={link}></AnswerImg>
<Answer>🌟{description}❄️</Answer>
<Button onClick={ () => {setInitial(true)} }>다시하기</Button>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

누나가 항상 버튼 태그에 type="button" 넣어주길래 왜지...? 싶었는데 이번에 궁금해서 찾아봤거든!!
https://nykim.work/96
처음 알았어..... 이렇게 오늘도 또 새로운 걸 알게 되었따 😌

Comment on lines +7 to +21
function CountDown() {
function Timer(){
const [time, setTime] = useState(3);

useEffect(() => {
time > 0 && setTimeout(() => setTime(time - 1), 1000);
}, [time]);

return time
? <Stage><NumEffect>{time}</NumEffect></Stage>
: <RandomResult></RandomResult> ;
}

return (<>{Timer()}</>);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

숭희 피드백 완전 좋다..... 유익해.....

color: white;
text-shadow: 3.2px 3.2px 0px ${({ theme }) => theme.colors.red}, 6.4px 6.4px 0px ${({ theme }) => theme.colors.darkRed};;

animation: ${blink} 1.025s step-end infinite;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

애니메이션 주는거 어떻게 하는지 잘 몰랐는데 끄적끄적..... 배워가요 ☺️

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전에 프로젝트 하면서도 생각 못 해봤던 방법인데 완전 좋다.....!! 코리 진짜 너무 유익해,,,,,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전역 스타일 파일은 js로 해주는 이유가 궁금했는데 성능상의 이유가 있었군용...!!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나도 이렇게 쓸 수 있다는 거 처음 알았엌ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 나두 나중에 써먹어봐야지!!!!! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants