Education/신한투자증권 프로 디지털 아카데미

React hook 알아보기

마이캣호두 2025. 6. 10. 01:54
반응형

신한투자증권 프로 디지털 아카데미 과정

 


지난 시간 복습✨

 
Props

부모 컴포넌트로 전달받는 파라미터
컴포넌트가 생성 될 때 부모로부터 받고 컴포넌트에 고정된 상태로 남아있음(변하지 않는 값)

 
State

컴포넌트 내에서 저장되고 유저의 이벤트나 시간에 따라 변화시킬 수 있는 값
State는 Props와 다르게 자체적으로 가지고 있는 것
초기화가 반드시 필요 < useState() 사용 >
State 변경 판단은 얕은 비교 - 참조값(주소값) 비교

  • 숫자나 문자열은 실제 값 자체를 비교
  • 객체는 값과 상관 없이 주소값을 비교
  • but 완전히 같은 객체를 다시 넣을 경우 렌더링 안 함
    그래서 상태로 객체나 배열을 쓸 때는 항상 새로운 객체로 만들어서 setState 해줘야 함

→ state 가 바뀔 때만 새로 그린다(자바스크립트를 다시 실행시킨다) : 이건 얕은 비교이다, 값까지 비교하지는 않는다
= 안 바뀌면 안 그린다!
 
Hook
함수형 컴포넌트 안에서 상태 관리나 생명주기 같은 기능을 쓸 수 있게 해주는 함수
리액트가 렌더링되는 과정에 “갈고리처럼” 내 코드를 끼워넣는다는 의미
훅을 사용하면 모든 컴포넌트를 독립적으로 재사용하는 게 가능

useCallback : 함수를 메모이제이션 (같은 함수 객체를 재사용) - 동일한 함수 객체를 유지하고 싶을 때
useMemo: 값(계산 결과)을 메모이제이션 (계산 결과를 저장해 재사용) - 무거운 연산 결과를 기억하고 싶을 때
 
 
 

3. React 본격 시작하기

 

1) useRef
: DOM에 직접 접근하거나, 렌더링과 관계없는 값을 기억할 때 쓰는 훅
State는 변경되면 다시 그리지만, ref는 값이 변경되어도 다시 그리지 않는다! 그래서 다른 컴포넌트를 참조하거나 값을 저장할 때 사용
 
2) React 기본

  • useMemo : 값을 메모이제이션 - 무거운 계산 결과를 캐싱해서 렌더링 때마다 다시 계산 안 하게 해줌
  • memo : 컴포넌트 자체를 메모이제이션 - props가 안 바뀌면 자식 컴포넌트를 다시 렌더링하지 않게 해줌, 함수형 컴포넌트를 감싸서 사용
  • useCallback : 함수 객체를 기억 - 렌더링 때마다 함수를 새로 만들지 않고 같은 함수 재사용하게 해줌, memo된 자식 컴포넌트에 함수 props 줄 때 꼭 필요함
  • useContext : 전역 상태를 컴포넌트들끼리 공유 - 부모 → 자식 → 손자에게 props 넘기지 않고 Context로 한 번에 전달해서 전역처럼 씀

calculatePrime 은 소수를 계산하는 함수인데, 시간 비용이 꽤 발생한다고 볼 수 있다. 무거운 계산 결과를 렌더링할 때마다 매번 다시 실행하는 것은 비효율적이기 때문에 useMemo 를 사용해서 최적화할 수 있다. 버튼을 클릭해도 값이 바뀌지 않는다면 다시 계산이 이루어지지 않는다. useState 로 limit 의 값이 바뀌는지 감시하고 있다가 input 에 새로운 값이 들어오는 경우에만 리렌더링 한다.
 

원래는  props 가 변경되지 않아도 부모가 리렌더링 되면 자식도 리렌더링 된다. 그런데 memo() 를 살펴보면 props 인 name 이 변경되었을 때만 리렌더링 된다는 것을 알 수 있다. props 가 변경되지 않으면 새로운 함수로 인식하지 않기 때문에 부모가 리렌더링 되더라도 이전 결과를 재사용해 최적화가 가능하다.
 

원래 memo() 는 props 가 바뀌지 않으면 재사용되지만, 위의 코드에서는 onClick 함수가 클릭될 때마다 매번 props 가 바뀌는 것처럼 인식되어 리렌더링이 발생한다. 그래서 똑같은 로직인데도 자식을 계속 호출하는 비효율적인 상황이 발생하므로 useCallback 을 사용하는 것이다.
 

useCallback 을 사용하지 않을 경우 부모 컴포넌트가 리렌더링 될 때마다 MemoizedButton 도 리렌더링되는 것을 볼 수 있다. useCallback 을 사용하는 경우 함수가 메모이제이션 되기 때문에 itemQty 가 변경되지 않는 경우 리렌더링 되지 않는다.
 

 
두 버튼 모두 state가 바뀔 때만 새 함수가 생성되고, 의존성 배열 [state] 덕분에 state가 같으면 이전 함수를 재사용한다. 렌더링할 때마다 함수가 새로 만들어지지 않는다는 공통점이 있다. 하지만 useCallback 은 이 함수 자체를 기억하는 것이고, useMemo 의 경우 값(여기에서는 함수)을 기억하는 것이다. 결과는 같지만 의미는 다름 .. 근데 보통 useCallback 을 많이 쓴다. 왜냐하면 이러한 상황에서의 목표는 어떤 함수를 다시 만들지 않고 기억해서 불필요한 리렌더링을 막는 것이기 때문! useMemo 는 캐싱을 목적으로 사용한다.
 

 
ThemeContext.jsx에서 Context 객체를 만들고, ThemeProvider.jsx에서 실제 상태(theme, toggleTheme)를 관리하면서 이 Context에 값을 공급한다. 그래서 컴포넌트 계층 구조 어디서든 theme 값을 공유할 수 있게 된다.
ThemeButton.jsx ThemePage.jsx에서 useContext(ThemeContext)로 현재 테마와 토글 함수를 받아오기 때문에, props를 중간중간에 안 넘기고도 필요한 곳에서 전역처럼 바로 값 사용이 가능하다.
ThemeProvider에서 setTheme으로 theme 값이 바뀌면, ThemeContext를 구독하고 있는 ThemeButton, ThemePage는 자동으로 리렌더링되므로 전역 상태처럼 동작하면서도 리액티브(반응형)하게 관리할 수 있다.

반응형