-
Notifications
You must be signed in to change notification settings - Fork 62
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
[7팀 김원표] [Chapter 1-3] React, Beyond the Basics #38
base: main
Are you sure you want to change the base?
Conversation
- 1. 두 값이 정확히 같은지 확인 (참조가 같은 경우) - 2. 둘 중 하나라도 객체가 아닌 경우 처리 - 3. 객체의 키 개수가 다른 경우 처리 - 4. 모든 키에 대해 얕은 비교 수행
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.
코드 너무 잘 봤습니다!
저와는 또 다르게 접근하시는 걸 보고 좋은 인사이트를 얻어간다고 생각이 듭니다!
이번 주차도 고생 많으셨고, 이후 주차도 화이팅입니다!
// 3. equals 함수를 사용하여 props 비교 | ||
if (prevProps.current === null || !_equals(prevProps.current, props)) { | ||
prevProps.current = props; | ||
return React.createElement(Component, prevProps.current); |
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.
저는 .tsx로 변경하고 <Component {...props} />
로 적용했거든요! 다른 분들도 이렇게 적용하시더라구요! 저도 이 방식으로 적용해볼 걸 그랬나봐요!
const ref = useRef<{ deps: DependencyList | null; value: T | null }>({ | ||
deps: null, | ||
value: null, | ||
}); |
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.
저는 이부분에 2개의 useRef를 선언했거든요!
depsRef
와 ref
를 각각 선언하고 각각 값을 할당해주는 방식으로 진행했어요! 이 부분도 오히려 이렇게 하나로 하는게 더 좋아보이네요!
interface ThemeContextType { | ||
theme: string; | ||
toggleTheme: () => void; | ||
} | ||
|
||
interface UserConTextType { | ||
user: User | null; | ||
login: (email: string, password: string) => void; | ||
logout: () => void; | ||
} | ||
|
||
interface NotificationContextType { | ||
notifications: Notification[]; | ||
addNotification: (message: string, type: Notification["type"]) => void; | ||
removeNotification: (id: number) => void; | ||
} |
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.
저는 이 방법이 제일 정석적인 방법이라고 생각이 들어요! 그래도 하나의 방법이 더 있긴한데 어떤 방법이나면
Pick이라는 것을 활용해보는 건데요! 외부 라이브러리의 타입이나 팀원과 공유하는 공통코드를 활용할 때 사용하면 좋을 듯 합니다! 생각해보니 DuckTyping 이라는 것도 있네요!
아래는 예시 코드도 보여드릴게요!
// 기존 코드 그대로 활용
interface AppContextType {
theme: string;
toggleTheme: () => void;
user: User | null;
login: (email: string, password: string) => void;
logout: () => void;
notifications: Notification[];
addNotification: (message: string, type: Notification["type"]) => void;
removeNotification: (id: number) => void;
}
// Pick 타입 사용으로 따로 코드를 추가로 선언할 필요 없이 사용 가능!
const ThemeContext = createContext<
Pick<AppContextType, "theme" | "toggleTheme"> | null
>(null);
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 ( | ||
typeof objA !== "object" || | ||
objA === null || | ||
typeof objB !== "object" || | ||
objB === null | ||
) { | ||
return false; | ||
} |
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.
위에서 primitive 타입을 걸러내고 여기서 따로 null과 undefined를 찾는 방법이네요!
저와는 다른 방식으로 접근하셔서 좋은 인사이트를 얻었습니다!
!Object.prototype.hasOwnProperty.call(objB, key) || | ||
objA[key] !== objB[key] |
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.
오 hasOwnProperty
를 사용해서 명시적이고 안전하게 키 검증이 되어서 좋아보이네요!
useCallback, | ||
useMemo, |
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.
하핫 코드 에디터에서 자동으로 import 해줬나보네요!😂 직접 구현하신 훅으로 적용해보는 것도 좋을 것 같아요!
과제 체크포인트
기본과제
심화 과제
과제 셀프회고
리액트의 기본 훅을 직접 구현하며 훅의 내부동작과 장점이 무엇인지 어떻게 사용해야하는지 알게되었다. 이전에 사용할 때는 주의점이나 올바른 활용방법을 충분히 알지 못한 채 사용했었지만, 이번 과제를 통해 기본 훅과 커스텀 훅에 대해 알게되었고, 설계 방향성을 고민해보는 시간이 되었다! 앞으로 기본적인 훅과 커스텀 훅을 활용하여 효율적인 코드를 작성할 수 있을 것 같다.
기술적 성장
훅에 대한 개념이 부족하다 생각해 기본 훅에 대해 집중적으로 학습했다. 그리고 사실 학습자료와 같은 내용이지만 한번 더 정리해보았다..ㅎ
React Hooks는?
함수형 컴포넌트에서 상태와 생명주기 기능을 사용할 수 있게 해주는 함수들.
⇒ 따라서 복잡한 로직을 가진 컴포넌트도 구조화하고 관리할 수 있다!
(개념도 모르고 쓰라길래 여기저기 사용하던)useState와 useEffect의 개념과 주의할 점은 다음과 같다.useState
함수형 컴포넌트에서 상태를 관리할 수 있게 해준다.
주의할 점으로는
useEffect
데이터 가져오기, 구독 설정, 수동으로 DOM 조작하기 등 컴포넌트의 주요 렌더링 작업 외의 작업들
주의할 점으로는
⇒ 함수형 컴포넌트에서 생명주기와 관련된 작업을 수행할 수 있게 해주는 강력한 도구
직접 구현해본 useRef, useMemo, useCallback의 개념과 주의할 점은 다음과 같다.
useRef
렌더링에 필요하지 않은 변경 가능한 값을 저장하는데 사용되는 Hook
주의할 점으로는
따라서, 렌더링과 관련된 값을 저장하는 데는 적합하지 않음
이는 메모리 누수를 일으킬 수 있으므로 필요하지 않은 경우 정리
useMemo
계산 비용이 큰 함수의 결과값을 메모이제이션하는 Hook
주의할 점으로는
잘못된 의존성은 최신 값을 사용하지 못하는 버그를 유발할 수 있음
useCallback
메모이제이션된 콜백 함수를 반환하는 Hook
주의할 점으로는
코드 품질
App.tsx는 관심사가 모두 모여있는 구조로 리팩토링이 필요할 것 같다. 현재 과제에서의 테스트 코드를 통과하는 포인트는 아니었지만 나중에 시간을 내서 관심사 분리와 컴포넌트 계층화 작업을 진행해야겠다는 목표를 세우게 되었다.
(설날, 쉬는 주차 Chapter1에 대해 전체적으로 리팩토링을 진행해보아야겠다)학습 효과 분석
과제에서 나오지 않은 기본 React Hooks들도 당!연!히! 살펴볼 필요가 있다고 느꼈다.
훅의 개념을 이해하는 데 시간이 오래 걸려 리팩토링을 진행하지 못한 점은 아쉬웠지만, 이번 과제를 통해 React가 왜 프레임워크의 대세가 되었는지, 그리고 그 장점이 무엇인지 깊이 알아가는 시간이었다. 단순히 사용만 했던 과거와 비교해 이제는 React의 원리와 효율성에 대해 더 명확히 이해하게 되어 의미 있는 성장이었다!
과제 피드백
훅을 직접 구현하고, 이를 활용하여 성능 최적화를 진행하며 기본과 심화 과제가 자연스럽게 연결되어있어 해결하고 이해하기 수월했다. 특히, 리액트의 내장 훅과 내가 직접 구현한 코드를 비교하며, 리액트가 제공하는 기본 훅들의 장점을 알았지만 동시에 이러한 훅들을 커스텀 훅으로도 충분히 구현하고 활용해볼 수 있겠다는 생각이 들었다.
그리고 조금 스스로 조금 아쉬운 점은 타입스크립트에 대한 이해도였다.. 이렇게 느낀 이유는 as T 와 같은 방식을 사용하여 해결했다는 점에서 타입스크립트를 보다 깊이 이해하고 활용하지 못해 아쉬웠다. 왜 특정 타입이 그렇게 결정되는 것인지 null로 들어올 수 있는 가능성에 대한 처리가 왜 필요한지를 명확히 이해하지 못하였다. 타입스크립트의 타입을 결정하는 시스템은 강력한 도구이지만, 그만큼 활용하고 충분히 이해하지 못해 아쉽고, 안정적이고 예측 가능한 코드를 작성할 수 있도록 노력해야겠다.
리뷰 받고 싶은 내용