[1팀 김휘린] Chapter 1-3. React, Beyond the Basics#38
Open
Hwirin-Kim wants to merge 18 commits intohanghae-plus:mainfrom
Open
[1팀 김휘린] Chapter 1-3. React, Beyond the Basics#38Hwirin-Kim wants to merge 18 commits intohanghae-plus:mainfrom
Hwirin-Kim wants to merge 18 commits intohanghae-plus:mainfrom
Conversation
jinsoul75
reviewed
Jul 25, 2025
Comment on lines
+8
to
+17
| if (Array.isArray(a) && Array.isArray(b)) { | ||
| // 길이가 다르면 false | ||
| if (a.length !== b.length) return false; | ||
| // 요소를 하나씩 비교 | ||
| for (let i = 0; i < a.length; i++) { | ||
| // 요소가 다르면 false | ||
| if (!Object.is(a[i], b[i])) return false; | ||
| } | ||
| return true; | ||
| } |
There was a problem hiding this comment.
배열의 타입은 'object'여서 이 코드가 없어도 테스트가 통과할 거에요 지금 utils 함수에서 배열 타입 체크 부분만 빼면요!
Object.keys() 메서드를 사용시 인덱스가 key가 됩니다 :)
jinsoul75
reviewed
Jul 25, 2025
| // 프롭스가 같으면 이전 결과 재사용 | ||
| return prevRef.current.result; | ||
| }; | ||
| return MemoizedComponent; |
There was a problem hiding this comment.
발제 자료를 보면 앞에서 만든 memo를 사용을 하라고 되어있어서 기존에 만들어두신 memo에 2번째 인자를 deepEquals 함수를 넘겨주면 더 간단하게 deepMemo를 완성할 수 있을것 같네용 :)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
과제 체크포인트
배포 링크
https://hwirin-kim.github.io/front_6th_chapter1-3/
기본과제
equalities
hooks
High Order Components
심화 과제
hooks
context
과제 셀프회고
이번 과제에서는 여러가지 리액트 훅을 만들어보고, 해당 훅으로 렌더링 최적화를 진행해보았다.
여러가지 의문점도 많이 생겼고 스스로 혼란에 빠지기도 했지만 분명히 이 경험은 내가 리액트를 이해하는데 큰 도움이 되었다.
기술적 성장
이번 과제에서 useRef를 useState를 사용하여 구현하는 과제가 있었다.
이렇게 간단하게 ref상태를 만드는데, 이 ref는 setState를 사용하지 않고 ref.current에 직접 값을 할당/변경 하여 useRef처럼 사용하는 방식이다.
setState로 새로운 객체를 생성하지도 않으니 값이 변해도 리렌더링 되지 않았다.
그런데 나는 여기서 의문이 들었다.
"일반 지역변수를 사용해도 렌더링이 발생하지 않는다면, 그냥 내부에 ref객체 변수를 만들어서 리턴하면 되지 않나?"
이렇게 말이다.
하지만 이것은 당연히 동작하지 않았다.
먼저 렌더링이 다시 발생할때마다 ref객체는 새 객체를 다시 만들어 반환하게 되기 때문이다.
즉, 값을 변경해서 저장하더라도 만약 렌더링이 다시 발생해버리면 이 값들은 다시 초기화 되버리는 것이다.
하지만 useState를 사용한다면 처음 렌더링시 객체를 생성하고, 해당 객체를 내부 hook 메모리에 저장해둔다.
이 후 렌더링시 저장해둔 값을 꺼내어 사용하는 방식이기 때문에 값을 기억할 수 있게 된다.
어떻게보면 너무나도 당연해서 위처럼 사용하지 않았지만, 진짜 안되는걸까? 하는 의문으로 실험해보니 더욱 이해가 잘되고 기억에 남았다.
앞으로도 간단해도 왜 안되는지 명확하지 않으면 직접 만들어 보는 수고(?)를 들여서라도 잘 공부해놔야겠다.
자랑하고 싶은 코드
지난번 과제까지도 그랬지만,, 테스트 통과를 위해 고민하고 통과해서 무언가 자랑하고 싶은 코드라고 할만한게 없는것 같다.. ㅠㅠ
그래도 하나를 뽑아본다면 얕은비교, 깊은 비교 함수를 만들 때 입력받은 파라미터 타입별로 다른 방법의 비교 방식을 취해줘야하는데
원시 데이터는 Object.is()메서드를 이용하면 간편히 가능했고, 배열의 경우 Array.isArray()메서드가 있어서 간단히 처리 되었지만, 객체의 경우 typeof value==="object" 만으로는 배열이나 Null을 걸러낼 수 없기 때문에 isPlainObject라는 유틸함수를 만들어 코드를 좀 더 깔끔하고 읽기 좋게 바꿨다는 점이다.
개선이 필요하다고 생각하는 코드
개선이 필요하다고 생각한 코드를 개선 후 아래 과제 피드백에 적었습니다!! 궁금했던 부분이 있어서요!
학습 효과 분석
이번 과제 중 Context API를 사용 할 때, 상태 컨텍스트와 액션 컨텍스트를 분리하여 재렌더링을 최적화 하는 부분이 있었다.
나는 현업에서 근무할때도 Context API를 자주 사용하곤했다. 그럼에도 이렇게 분리하여 최적화 할 수 있다는것을 왜 생각하지 못했을까..?
이번 과제를 하면서 어떤 코드든지 더 개선할수없을까? 하는 고민을 해봐야 한다고 생각했다.
물론 이를 사용하는 컴포넌트가 상태와 액션을 모두 사용한다면 굳이 컨텍스트를 나누지 않아도 성능은 똑같을 수 있다.
하지만 이번 과제를 통해 이런 방법도 있다는걸 배웠으니 꼭 적용해봐야겠다.
과제 피드백
전체적으로 이번 과제는 AI사용이 제일 적었고, 반대로 깊이 생각한 시간은 많았다.
과제 자체의 난이도는 낮은편이라고 들었는데, 나는 오히려 지난 과제들보다 고뇌하는 과정이 더 많았어서 난이도가 높게 느껴졌다.
그리고 이번 과제부터 타입스크립트를 사용하였는데, 원래 현업에서도 계속 사용했지만, 뭔가 그때보다 어렵게 다가왔다.
전반적으로 잘 마무리해서 기분은 뿌듯하다!
학습 갈무리
리액트의 렌더링이 어떻게 이루어지는지 정리해주세요.
이번 1,2,3주차 과제를 진행하며 내가 이해한 개념들
메모이제이션에 대한 나의 생각을 적어주세요.
리액트 메모이제이션은 불필요한 렌더링이 발생할 때 필요하다.
그럼 어떤 환경이 불필요한 렌더링일까?
사실 성능 저하가 거의 없는 경우 불필요한 렌더링일지라도 굳이 성능개선을 할 필요는 없다고 생각한다.
그래서 내가 생각했을 때 다음과 같은 상황에서 사용해야한다고 생각한다.
그럼 언제 불필요할까?
메모이제이션을 사용하지 않고 해결할 수 있는 방법은 무엇일까?
메모이제이션을 사용했을 때의 장점과 단점은 무엇일까?
장점
단점
컨텍스트와 상태관리에 대한 나의 생각을 적어주세요.
컨텍스트와 상태관리가 필요한 이유는 무엇일까?
컨텍스트와 상태관리를 사용하지 않으면 어떤 문제가 발생할까?
컨텍스트와 상태관리를 사용했을 때의 장점과 단점은 무엇일까?
장점
단점
컨텍스트와 상태관리를 사용하지 않고도 해결할 수 있는 방법은 무엇일까?
컨텍스트와 상태관리를 사용할 때 주의해야 할 점은 무엇일까?
리뷰 받고 싶은 내용
위는 이번 과제에 진행했던 useRouter를 구현하는 함수입니다.
처음엔 useSyncExternalStore에 구독 해지 함수를 딱히 넣어주지 않았습니다. router.unsubscribe라는 메서드가 딱히 존재하지 않았고, 이렇게 둬도 동작을 하기에.. 이해도가 부족한 상태에서 뭔가 더 건드리고 싶지 않아서 일단은 넘어갔습니다.
그런데 이렇게 두면 컴포넌트가 언마운트 되어도 useRouter를 호출했던 컴포넌트 수 만큼 메모리 낭비가 이뤄지는게 아닌가 하는 생각이 들었습니다. (그저 단순한 제 추측이긴합니다..)
그래서 Router에 빠져있던 unsubscribe를 추가하고 아래와 같이 수정했습니다.
위처럼 수정했지만 사실 딱히 체감되는건 없었습니다.. 그래서 어떻게 확인해볼 방법이 없을까? 고민했지만 딱히 방법을 찾지 못했습니다.
구독해지가 안되어있을때 정말 메모리 낭비가 이뤄지는지, 그걸 어떻게 확인할 방법이 있는지 궁금합니다.