리액트 훅 개요
훅은 리액트 컴포넌트에서 상태와 이펙트를 도입하고 관리하는 효과적인 매커니즘입니다.
훅이 뭡니까?
앞 장에서는 리액트 컴포넌트가 특정 props
객체에 의존해서 UI를 나타내는 단순한 함수임을 배웠습니다. 이를 유용한 애플리케이션으로 만드려면 사용자 입력 혹은 서버의 데이터 요청과 같은 상황과 상호작용이 이루어지도록 props
를 조작할 방법이 필요합니다.
훅(Hook)
은 HTTP 요청, 직접적인 DOM 조작, window 사이즈 쿼리 등 다양한 작업에 대해 컴포넌트 상태에 접근하며 사이드 이펙트를 트리거할 수 있는 함수입니다.
다시 말하자면, 훅은 리액트 기능에 연결(hook into)할 수 있게 해줍니다
useState 훅 예제
어디 간단한 예제를 살펴볼까요. 여기 간단한 Counter
예제가 있습니다. Counter
컴포넌트는 사용자가 버튼을 클릭해 각 버튼 클릭할 때 즉시 렌더링되는 count
값을 증가시킬 수 있습니다.
/* Counter.re */@react.componentlet make = () => {let (count, setCount) = React.useState(_ => 0);let onClick = (_evt) => {setCount(prev => prev + 1)};let msg = "You clicked" ++ Belt.Int.toString(count) ++ "times"<div><p>{React.string(msg)}</p><button onClick> {React.string("Click me")} </button></div>}
여기서 우린 React.useState
훅을 사용했습니다. 우리는 컴포넌트 함수 내에서 훅을 호출하여 로컬 상태를 하나 추가했습니다. 리액트는 컴포넌트를 렌더링하거나 다시 렌더링 하는 도중에 이 상태를 보존합니다. React.useState
는 튜플을 반환합니다. 현재 상태 값과 (count
) 그 상태를 업데이트 할 수 있는 함수(setCount
)를 반환합니다. 우리는 이 함수를 이벤트 핸들러에서 호출하거나 다른 컴포넌트로 전달하여 호출할 수 있습니다.
React.useState
의 유일한 인자는 초기 상태를 반환하는 함수입니다. (_ => 0
) 위 예제에서 0은 우리가 초기값을 0으로 시작했기 때문에 0입니다. 상태는 어떠한 타입도 될 수 있습니다. 리스크립트
는 타입을 추론합니다. (타입과 일치하는 초기 상태를 반환해야합니다) 초기 상태는 첫번째 렌더링에서만 사용됩니다.
이건 우리의 첫 훅 사용에 대한 간단한 예제입니다. 더 자세한 부분은 useState 섹션에서 다룰 예정입니다.
사용 가능한 훅
참고 모든 훅은 React
모듈의 일부분입니다. (예를들어 React.useState
처럼)
기본 훅:
- useState: 컴포넌트에 지역 상태를 추가합니다.
- useEffect: 컴포넌트 안에서 사이드 이펙트를 발생시키는 부분을 실행합니다.
- useContext: 컴포넌트에 리액트 컨텍스트 값을 제공합니다.
추가적인 훅:
- useReducer:
useState
의 변형입니다. 상태 / 액션 / 리듀스 패턴을 사용할 수 있습니다. - useRef: 변형 가능(mutable)한 리액트-Ref 값을 반환합니다.
훅 규칙
훅은 그저 함수입니다. 그러나 훅을 사용할 때는 두가지 규칙을 따라야 합니다. 리스크립트는 컴파일러에서 이 규칙을 강제하지는 않습니다. 때문에 만약 훅 컨벤션 룰을 강제하고 싶다면 자바스크립트로 변환된 결과물에 eslint-plugin를 적용할 수 있습니다.
규칙 1) 가장 상위(at the top level)에서만 훅을 호출해야 합니다.
반복문, 조건문, 중첩된 함수 내에서 훅을 호출하지 마세요 대신 리액트 함수 가장 상위 레벨에서 훅을 사용해야 합니다. 이 규칙을 따르면 컴포넌트가 렌더링 될 때마다 동일한 순서로 훅이 호출됩니다. 이 때문에 리액트가 여러 useState
, useEffect
의 호출 사이에서 훅 상태를 올바르게 보존할 수 있게 합니다. (이 부분이 더 궁금하다면, 자세한 설명은 ReactJS Hooks docs 문서를 읽어보세요)
규칙 2) 리액트 함수에서만 훅을 호출할 수 있습니다.
리액트 함수가 아닌 일반 함수에서 훅을 호출하지 마세요
- ✅ 리액트 함수 컴포넌트에서 훅 호출
- ✅ 커스텀 훅에서 훅 호출 (custom hooks 섹션에서 더 자세히 다룰 것입니다).
이 규칙을 따르면, 컴포넌트 내부 상태에 대한 모든 로직이 명확하게 소스 코드 레벨에서 확인 가능합니다.