elice/토끼성장일지

[엘리스 AI트랙] 03-04-03 React기초 2 (Hook)

Juliie 2021. 10. 13. 00:23
TIL은 오늘 하루 새롭게 알게 된 내용 위주로 작성하고 있어요 ✏️

 

1. Hook

  • 컴포넌트에서 데이터를 관리(State)하고 데이터가 변경될 때 상호작용(Effect)을 하기 위해 사용
  • State Hook의 대표적인 예로 useState가 있음
  • 다른 컴포넌트와 Hook 내에서만 사용 가능
  • 이름은 반드시 use로 시작
  • 최상위 level에서만(첫번째 중괄호) hook 호출 가능 ⭐️

왜 Hook이 등장했냐면...

  • 기존에는 컴포넌트 내에서 state와 생명주기를 관리하기 위해서 반드시 클래스형 컴포넌트를 사용
  • 다소 복잡한 클래스형 컴포넌트를 보완하고 함수형 컴포넌트에서도 해당 기능을 사용할 수 있도록 이후 추가됨

 

(1)State Hook

  • useState: 컴포넌트 내 동적인 데이터를 관리할 수 있는 hook
  • state는 읽기전용! 직접 수정 금지
  • state를 변경할 때는 꼭 setState 이용하기, 이 때 자동으로 컴포넌트가 재렌더링 됨

 

(2)Effect Hook

side effect: 컴포넌트 안에서 데이터를 가져오거나 구독하고, DOM을 직접 조작하는 작업을 이전에도 종종 해보셨을 것입니다. 우리는 이런 모든 동작을 “side effects”(또는 짧게 “effects”)라고 합니다. 왜냐하면 이것은 다른 컴포넌트에 영향을 줄 수도 있고, 렌더링 과정에서는 구현할 수 없는 작업이기 때문입니다."
  • 컴포넌트가 최초로 렌더링될 때, 지정한 state나 props가 변경될 때 마다 이펙트 콜백 함수가 호출됨
  • Deps: 변경을 감지할 변수들의 집합(배열)
  • EffectCallback: Deps에 지정된 변수가 변경될 때 실행할 함수
  • https://ko.reactjs.org/docs/hooks-overview.html#effect-hook
  • 예시 코드
useEffect(() => {
	console.log(`버튼을 ${count}회 클릭했습니다.`)
}, [count])

 

const App = () => {
	useEffect(() => {
    	    const intervalId = setInterval(() => {
        	console.log("안녕하세요");
        }, 1000);
        
        return () => {
        	clearInterval(intervalId);
        }
    }, [])
....
  • deps에 넘겨진 값이 없어도 컴포넌트가 생성될 때 한번은 실행이 됨(➡️ 컴포넌트가 생성될 때 한번만 실행해줘!)
  • useEffect의 이펙트 함수 내에서 다른 함수를 return할 경우 state가 변경되어 컴포넌트가 다시 렌더링 되기 전과 컴포넌트가 소멸할 때 호출할 함수를 지정하게 됨
  • 컴포넌트를 재렌더링 하기 전에, 컴포넌트가 없어질 때 clearInterval 함수 실행

 

(3) 그 외의 Hook

 

① useMemo

  • 지정한 state나 props가 변경될 경우 해당값을 활용해 계산된 값을 메모이제이션하여 재렌더링시 불필요한 연산을 줄여줌(변수 메모)
  • 계산한 값을 메모리에 저장해야 하므로 성능 이슈 발생 가능성 있음

 

② useCallback

 

  • 함수를 메모이제이션하기 위해 사용하는 hook
  • 컴포넌트가 재렌더링 될 때 불필요하게 함수가 다시 생성되는 것을 방지
  • useMemo(() => fn, deps) 와 useCallback(fn, deps)는 같음

 

③ useRef

  • 컴포넌트 생명 주기 내에서 유지할 ref 객체를 반환
  • 다시 렌더링 되지 않아야 할 객체가 있을 때 사용
  • ref 객체는 .current라는 프로퍼티를 가지며 이 값을 자유롭게 변경할 수 있음
  • useRef에 의해 반환된 ref 객체가 변경되어도 컴포넌트는 재렌더링 되지 않음
  • 일반적으로 리액트에서 Dom Element에 접근할 때 사용