Hook의 개요
Hook은 Class를 작성할 필요없이 함수형 컴포넌트에서 상태값을 사용할 수 있는 방식이다. React 버전 16.8부터 새로이 적용되었다. 공식문서의 Hook이 만들어진 이유를 읽어보면, 기존에는 Lifecycle을 중심으로하여 State와 메서드가 뒤섞이고 복잡해지면서 컴포넌트가 방대해지는 문제가 있었다. 그리고 Javascript의 Class 코드의 재사용성 저하와 코드 구성 난해함을 해결하기 위해 Hook을 사용하기 시작했다고 되어있다.
https://ko.reactjs.org/docs/hooks-intro.html#motivation
자세한 동기
Class 컴포넌트로 작성하다보면 Wrapper hell 이라는 현상이 발생하게 된다. 컴포넌트를 다른 컴포넌트로 감싸주는 구조이기 때문에, 하나의 컴포넌트를 표현하기 위해서 다른 포장지 역할만 하는 컴포넌트만 여러 개 사용이 되어 불합리점이 발생한다.
componentDidMount, componentDidUpdate, componentWillUnmount와 같은 Lifecycle에 각 컴포넌트를 어떻게 배치해야하는지 알아야 하고, 정확히 어떤 구동을 해야하는지 생각해야하며 코드의 가독성도 떨어지게 된다.
>> useEffect()를 이용해서 간편하게 관리할 수 있다!
메서드를 여러 개 사용하는 경우, this를 bind해주는 코드를 중복적으로 다수 작성해야한다. 또한 render 부분에서 메서드 이름을 다시 작성해주어야 하므로 불편하고, 실수가 많이 발생한다.
Hooks를 어떤 방식으로 작성하는지 전체적인 코드만 살펴보자.
역시 제일 만만한 예제인 버튼 클릭 시 값이 증가하는 카운터 예시를 들어놨다.
여기서는 useState만 사용하는데, count라는 상태를 정의하고 그것을 기존처럼 setState를 통해서 바꾸는게 아니라
count라는 상태와 count 상태를 관리하는 setCount 메서드가 쌍으로 존재한다.
아래에서는 count와 setCount라고 상태값과 상태값 변경 메서드를 이름 지었지만, 이것은 관습에 의한 것이지 꼭 이럴 필요는 없다. 그냥 [book, paper] 등과 같이 아무렇게나 지어도 된다. Array의 첫번째 요소가 state, 두번째 요소가 메서드인 것이다.
만약 아래와 같은 코드에서 setCount는 안쓰고 count라는 state만 쓰고 싶다면,
const count = useState(0)[0];
이라고 쓰면 된다.
UseState
useState는 현재의 state값과 이 값을 업데이트하는 함수를 쌍으로 제공한다.
기존 React 방식과 유사하지만, 기존 방식처럼 새로운 state를 생성하여 기존 state를 업데이트하는 방식이 아니다. 또한 꼭 객체일 필요가 없다.
정의된 함수는 이벤트 핸들러나 다른 곳에서 호출하여 사용할 수 있다.
아래 상태관리 예제를 하나 더 보면, isLightOn이라는 상태와 상태관리 함수를 쌍으로 정의하고, useState로 기본값을 false로 두었다.
그리고 11번 줄에서 isLightOn이라는 상태를 검사하여 true이면 switchOnImg를 img 태그의 src로 가져오고, false이면 switchOffImg를 src로 가져도오록 하였다.
또한 onClick 이벤트를 달아주어서 클릭 시 setIsLightOn 상태 관리 함수가 실행되어 현재 isLightOn값을 전환할 수 있게 하였다.
(true 이면 false, false 이면 true로 변경되도록 !isLightOn 적용)
useEffect
React class 에서의 componentDidMount, componenetDidUpdate, componentWillUnmount와 같은 목적으로 사용되나, 하나의 API로 통합되었다.
useEffect를 사용하면 React는 DOM을 바꾼 뒤에 "effect" 함수를 실행한다. 기본적으로는 첫 번째 렌더링을 포함하여 매 렌더링 이후에 effects를 실행한다.
아래의 예제를 통해 더 상세히 알아보자.
useEffect(() => { }, [ ] )의 형태를 띄고 있다.
isLineTouched, isDragHovered의 2가지 상태값을 쓰고 있는데, 내용보다는 구조에 집중하자.
무명함수 ( ()=> {} ) 로 정의된 부분에서는 해당 컴포넌트가 실행되자마자 실행될, 즉 componentDidMount에 관한 내용들을 작성한다.
배열 [] 부분에서는 변경을 추적하고 싶은 상태값 등을 넣는다. 즉 componentDidUpdate를 할 부분을 적어주는 것이다.
Hook 사용 규칙
2가지 사용 규칙을 준수해야 한다.
- 함수컴포넌트의 최상위레벨에서만 Hook을 호출해야 한다. 반복문, 조건문, 중첩함수 내에서 Hook을 실행하면 안된다.
- 일반 Javascript에서 Hook을 호출하면 안된다.
위 두가지 규칙을 강조하기 위해서 linter plugin을 제공하고 있다.
참조
설치 및 사용법 : https://www.npmjs.com/package/eslint-plugin-react-hooks
'Programming-[Frontend] > ReactJS' 카테고리의 다른 글
React / Router (0) | 2020.10.19 |
---|---|
React / 기초2 / State, props와 클래스 컴포넌트 작성 : dark mode 구현해보기 (0) | 2020.10.14 |
React / 기초4 / 이벤트 처리하기 (0) | 2020.10.06 |
React / 기초3 / LifeCycle (0) | 2020.10.06 |
React / 기초1 / React 설치, JSX, component (0) | 2020.10.05 |