-
Notifications
You must be signed in to change notification settings - Fork 37
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
[2단계 - 계산기] 호프(김문희) 미션 제출합니다. #46
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.
호프님 안녕하세요~
리액트 함수형은 또 다르지요?
기존 코드를 최대한 유지하려고 하신 것 같은데, 리액트는 리액트만의 '랜더링 최소화'를 위한 기법들이 많이 존재합니다. 그 기본 철학에 충실히 따른 코드는 아닌 것 같아요. 이에 대해서는 코멘트 남겼으니 확인해보시면 좋겠습니다.
추가로 리뷰요청시에 엄청 긴 글을 작성해주셨는데, 이와 관련하여 몇가지만 덧붙여보겠습니다.
- 3자리가 넘어 간 후에 숫자를 입력 할 시 마지막 자릿수를 수정해주는 식으로 해결
: 사용자 입장에서 괜찮은걸까요? 계산기 상단에 문구를 남겨놓으셔서 '3자리수까지만 입력 가능하다'는 사실은 인지가 가능�하지만, 그렇다고 '마지막 자릿수가 변경된다'는걸 인지하기는 어렵고 당황스러울 것 같다는 의견입니다. - "출력값 있는 상황에" 페이지 이탈시 이탈 여부를 확인
: 맞습니다. 다만 항상 그렇게 동작하지는 않는것 같은데, 이부분은 넘어가도 될 것 같네요 :) - 버그제보) AC를 눌러
0
이 표기된 상태에서 새로고침하면 localStorage에 저장되지 않고, 이탈여부를 확인하지도 않으며, 새로고침 완료시 기존 값이 다시 로드되고 있습니다.
React 체험 성격의 미션이라 바로 승인 및 머지할게요. 위 내용은 참고만 하세요. 고생하셨습니다 :)
const Calculator = () => { | ||
const [state, setState] = useState({ | ||
firstOperand: 0, | ||
secondOperand: -1, |
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.
초기값이 -1인 이유는 뭔가요?
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.
이 부분 뒷자리 숫자가 '없다'라는 것을 표현해주기 위해서 일단 -1로 초기화해주었는데요, 0 으로 바꾸는게 더 맞다고 판단됩니다. 지적해주셔서 감사합니다.
operation: null, | ||
isError: false, | ||
}); | ||
const handleWindowClose = (e) => { |
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.
이 함수를 어떤 이유에서 이렇게 작성하셨는지는 이해하겠습니다. 다만 함수의 쓰임새가 useEffect 안에서만 이뤄지고 있으니, useEffect 안으로 옮기시는 편이 더 나을 것 같아요. 현재 상태로는 Calculator가 render될 때마다 새롭게 정의되는 거거든요.
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.
넵! 일단 함수를 다 분리한다는 목적으로 했는데, 렌더될때마다 함수가 새로 생성되어서 성능상 좋지 못하다는 것은 간과했네요 😭 지적해주셔서 감사합니다.
secondOperand: -1, | ||
operation: null, | ||
isError: 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.
하나의 state에 모든 정보를 객체형태로 넣는 것은 안티패턴입니다.
이상태로는 어떤 값 하나만 변경되더라도 변경되지 않은 다른 모든 하위컴포넌트가 다시 렌더될거에요.
변경된 부분만 렌더링하자! 라는 리액트의 컨셉에 정면으로 배치되는 셈이죠.
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.
저는 일단 계산기 내에서 각각 상태값이 거의 함께 변경되어서 객체형태로 수정해주었는데요,
로이님 말씀을 듣고보니까 불필요한 하위 컴포넌트의 리렌더링을 일으킬 수 있겠군요! 지적해주셔서 감사합니다 :)
안녕하세요 로이님, 간단한 미션이었는데도 좋은 리뷰 주셔서 정말 감사드려요! |
데모페이지
안녕하세요 로이님 :) 다시한번 인사드려요. 먼저 ,저번 리뷰 정말 감사했습니다. 놓쳤던 부분들을 짚어주셔서 큰 도움이 되었어요 👍 👍 👍
그럼 먼저 수정한 사항들을 간략하게 설명해드리겠습니다.
✨ 기능 오류 해결
✨ 리팩토링
컴포넌트 분리
조금씩 연산이 늘다보니, Calculator 컴포넌트가 너무 복잡해지는 것 같아서, 컴포넌트를 분리해보았습니다.
Calculator, Digits(숫자), Operations(연산자), Expression(출력값), Modifier(AC 버튼)
로 분리이벤트 위임 제거
()=> onClick(digit)
이런 식으로 새로 함수를 생성해주었는데요, 리팩토링하여 커링함수로 핸들러 함수를 선언해주어onClick=(digit)=>()=>{..}
이러한 문제점을 해결했습니다 :)그리고, Hooks 로 수정하면서 여러 문제점들을 마주했고, 아래와 같은 시도를 해보았습니다.
✨Hooks 관련 사항들
1. useLayoutEffect 사용
로컬스토리지에 저장된 값을 가져와서 state 에 저장해줄 때, useLayoutEffect 라는 api 를 사용했습니다. 사용한 이유는 아래와 같아요.
2. Ref 사용
사실 ref 사용하신 걸 보고 의아해 하실 수도 있는데요! 저는 아래와 같은 문제점을 해결하고자 ref 를 사용해보았어요.
마주한 문제
beforeunload
이벤트에 대한 핸들러를 초기 렌더링에 등록 해야 했습니다.계산기 상태가 초기값인지 확인하고
, 초깃값이 아니라면 (= 출력값이 있다면)변화된 계산기 상태를 로컬스토리지에 저장
해야 했습니다.주어진 해결방법
선택한 해결방법
제 생각에는 2번의 방법이 훨씬더 비용상으로 효율적이라고 생각했기 때문에 2번 방법을 선택했습니다. 매번 이벤트를 등록하는 것 보다 Ref 를 수정하는게 효율적이라고 판단했습니다.
3. React.Memo & useCallback 사용 기준
리렌더링 될 때 함수가 새로 생성되는 비용 < useCallback의 메모이제이션 비용
이라고 생각했기 때문입니다. 따라서 현재 어플리케이션 사이즈에서는 오히려 useCallback 으로 계속 메모이제이션 시켜주는게 더 성능상 좋지 않을거라고 판단했어요.hooks로 바꾸면서 조금 과하게 사용한 부분도 없지않아 있는 것 같은데, 여러가지를 학습하는데 중점을 두어 보았습니다 : D
그럼 다시한번 감사드립니다 💯