이번 주차는 React Hook에 대해 깊이 있게 학습하고, 함수형 프로그래밍의 핵심 개념들을 실제 코드로 구현해보는 시간이었다. 특히 상태 관리와 컴포넌트 설계에서 많은 고민과 배움이 있었다.
상태 추상화와 Hook 설계
도메인 기반 모듈화
전역 상태 관리
Props drilling을 피하려다가 큰 함정에 빠졌다. 하위 컴포넌트에서 같은 커스텀 훅을 다시 호출하면 상태가 공유될 거라 생각했는데, 완전히 독립적인 상태가 생성되었다.
function ParentComponent() {
const { addNotification } = useNotification();
addNotification('성공');
return (
<div>
<ChildComponent /> {/* props로 전달하지 않음 */}
</div>
);
}
function ChildComponent() {
const { addNotification } = useNotification(); // 같은 훅을 다시 선언
// 하지만 Parent의 상태와는 완전히 분리됨!
}
이 실수를 2번이나 반복하면서 깨달았다: 커스텀 훅은 로직 재사용을 위한 도구이지, 상태를 공유하는 것이 아니다. 각 호출마다 새로운 상태 인스턴스가 생성된다는 React Hook의 기본 원칙을 체감했다.
두 개의 독립적인 상태 저장소를 동기화하는 과정에서 많은 고민이 있었다:
처음 접근한 방식은 useEffect를 통한 단방향 동기화였다:
const [value, setValue] = useState(() => {
const saved = localStorage.getItem(key);
return saved ? JSON.parse(saved) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [value, key]);
하지만 이 방법은 상태 업데이트 시점에서 일관성 문제가 발생했다. 팀원들과의 코드 공유를 통해 Single Source of Truth 패턴을 적용한 해결책을 찾을 수 있었다:
const setValue = (value: T | ((val: T) => T)) => {
setStoredValue((prev) => {
const newValue =
typeof value === "function" ? (value as (val: T) => T)(prev) : value;
if (
newValue === undefined ||
(Array.isArray(newValue) && newValue.length === 0)
) {
localStorage.removeItem(key);
} else {
localStorage.setItem(key, JSON.stringify(newValue));
}
return newValue;
});
};
핵심 차이점은 실행 시점이었다:
4주차에 바이브코딩을 하면서 큰 현타가 왔었다. AI에게 의존하면서 테스트 통과만을 목표로 하다 보니, "내가 뭘 하고 있는 거지?"라는 생각이 들었다. 교육의 진짜 목적은 스스로 배워가는 것인데, 언제부터 테스트 통과가 최우선이 되었을까?
5주차에서는 다시 초심으로 돌아가 AI 도움을 최소화하고, 팀원들과의 코드 리뷰와 페어코딩을 통해 하나씩 부딪혀가며 배웠다. 처음엔 내 질문이 상대방의 시간을 빼앗는다고 생각했지만, 오히려 서로 설명하고 토론하면서 win-win 관계가 형성되었다.
이번 과제에서 가장 신경 쓴 부분은 컴포넌트 분리였다:
"더 세세하게 나누는 게 좋을까? (ProductImg, ProductDiscount, ProductPrice 등) 아니면 큼직하게 나누는 게 좋을까? (ProductCard < ProductList)"라는 고민이 계속 있었다. 결국 재사용성과 유지보수성을 기준으로 판단해야 한다는 걸 배웠다.
커스텀 훅을 직접 설계하면서 깨달은 것:
원래 목표는 몰랐던 부분을 천천히 학습하며 과제를 진행하는 것이었다. 그러나 진도가 늦어지면서 제출일이 다가올수록 테스트 통과에만 집중하게 되었다.
다른 사람의 PR을 참고하거나 AI를 활용하면서 스스로 고민할 기회가 줄어든 점이 아쉬웠다.
더 많은 시간을 투자하여 온전히 내 힘으로 과제를 진행했다면 더 깊은 배움과 성장이 있었을 것이다. 클린코드 과제에서는 특히 이런 아쉬움이 크게 남았다.
다음에는 반드시 스스로 생각하며 내 힘으로만 과제를 완성하는 것을 목표로 한다. 그렇게 해야 진정으로 내 것이 될 수 있다.
이번 주는 비록 완벽하지 않았지만, 팀원들과 함께 학습하는 즐거움을 다시 느낄 수 있었다. 다음 주차에서도 더 많은 페어코딩과 협업을 통해 성장하고 싶다!