EnJinnier
처음 만난 리액트 - 8. Hooks 본문
Hooks의 개념
일반적으로 함수 컴포넌트는 클래스 컴포넌트와 다르게 대부분의 기능이 지원되지 않는다.
따라서 함수 컴포넌트에 클래스 컴포넌트와 동일한 기능을 지원하기 위해서 나온 것이 바로 Hook이다.
React의 state와 생명주기 기능의 갈고리(hook)를 걸어 원하는 시점에 정해진 함수를 실행되도록 만들었고,
이때 실행되는 함수를 Hook이라고 한다.
Hook의 이름은 모두 use로 시작한다.
대표적인 훅들에 대해 알아보자.
useState()
- state를 사용하기 위한 hook
예시로 이해해보자.
여기 버튼을 클릭하면 카운트를 하나씩 증가시키고 현재 카운트를 보여주는 카운터 함수 컴포넌트 코드가 있다.
그런데 만약 카운트를 함수의 변수로 선언해서 사용하게 되면 버튼 클릭 시 카운트 값을 증가시킬 수는 있지만 재렌더링이 일어나지 않아 새로운 카운트 값이 화면에 표시되지 않게 된다.
따라서 이런 경우에는 state를 사용해서 값이 바뀔 때마다 재렌더링 되도록 해야 하는데
함수 컴포넌트에는 해당 기능이 따로 없기 때문에 useState를 사용하여 state를 선언하고 업데이트해야 한다.
useState() 훅은 다음과 같이 사용한다.
- useState를 호출할 때에는 파라미터로 선언할 state의 초기값이 들어간다.
- 이렇게 초기값을 넣어 useState를 호출하면 return 값으로 배열이 나온다.
return된 배열에는 두 가지 항목이 들어 있는데
- 첫 번째 항목은 state로 선언된 변수
- 두 번째 항목은 해당 state의 set 함수
이다.
실제 useState를 사용하는 코드를 보자.
이 코드는 useState를 사용하여 카운트 값을 state로 관리하도록 만든 것이다.
(클래스 컴포넌트에서는 setState 함수 하나를 사용해서 모든 state 값을 업데이트할 수 있었지만 useState를 사용하는 방법에서는 변수 각각에 대해 set함수가 따로 존재한다는 것이 다르다.)
useEffect()
- Side effect를 실행하기 위한 Hook
- 클래스 컴포넌트에서 제공하는 생명주기 함수인 componenetDidMount, componentDidUpdate, componentWillUnmount와 동일한 기능을 하나로 통합해서 제공함.
(*Side effect : 서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 등의 작업. 이 작업들이 다른 컴포넌트에 영향을 미칠 수 있으므로 렌더링이 끝난 후에 실행된다는 의미에서 사이드 이펙트라고 칭함 )
(*의존성 배열: 이 이펙트가 의존하고 있는 배열. 배열 안에 있는 변수 중에 하나라도 값이 변경되었을 때 이펙트 함수가 실행됨)
의존성 배열 []로 할시 : mount와 unmount시에 단 한 번씩만 실행됨
의존성 배열 생략시: 컴포넌트가 업데이트될때마다 호출됨
useEffect에서 리턴하는 함수는 컴포넌트가 mount 해제, 즉 unmount될 때 호출됨 (componentWillUnmount와 동일한 역할)
이펙트는 함수 컴포넌트 안에서 선언되기 때문에 해당 컴포넌트의 props와 state에 접근할 수도 있다.
useMemo()
- Memorized value를 리턴하는 Hook
Memoized value란?
Memoization : 연산량이 많이 드는 함수의 호출 결과를 저장해 두었다가 같은 입력 값으로 함수를 호출하면 새로 함수를 호출하지 않고 이전에 저장해 놨던 호출 결과를 바로 반환하는 것.
이때 memoization이 된 결과 값을 memoized value라고 부름.
- useMemo 훅은 파라미터로 memoizedValue를 생성하는 create함수와 의존성 배열을 받는다.
- 의존성 배열에 들어있는 변수가 변했을 경우에만 새로 create함수를 노출하여 결과값을 반환하며 그렇지 않은 경우에는 기존함수의 결과값을 그대로 반환한다.
- 다만, useMemo로 전달된 함수는 렌더링이 일어나는 동안 실행되기 때문에 일반적으로 렌더링이 일어나는 동안 실행돼서는 안될 작업을 useMemo의 함수에 넣으면 안된다.
- 대부분 useMemo 훅에 의존성 배열의 변수들을 넣고 해당 변수들의 값이 바뀜에 따라 새로 값을 계산해야 할 경우에 사용함.
useCallBack()
- useMemo() Hook과 유사하지만 값이 아닌 함수를 반환
- 쉽게 말하면 컴포넌트가 렌더링 될 때마다 매번 함수를 새로 정의하는 것이 아니라 의존성 배열의 값이 바뀐 경우에만 함수를 새로 정의해서 리턴해 주는 것
-useMemo와 마찬가지로 함수와 의존성 배열을 파라미터로 받음.(이때 파라미터로 받는 이 함수를 callBack이라고 부름)
useRef()
- Reference를 사용하기 위한 Hook
(*레퍼런스: 특정 컴포넌트에 접근할 수 있는 객체)
- useRef() Hook은 이 레퍼런스 객체를 반환함
- 내부의 데이터가 변경되었을 때 별도로 알리지 않음. (그래서 커런트 속성을 변경한다고 해서 재렌더링이 일어나진 않음)
- 레퍼런스 객체에는 current라는 속성이 있는데 이것은 현재 레퍼런스하고 있는 엘리먼트를 의미함.
- 파라미터로 초기값을 넣으면 해당 초기값으로 초기화된 레퍼런스 객체를 반환
- 이렇게 반환된 레퍼런스 객체는 컴포넌트의 라이프타임 전체에 걸쳐서(=즉 컴포넌트가 마운트 해제 전까지) 계속 유지됨
Hook의 규칙
1. Hook은 무조건 최상위 레벨(React 함수 컴포넌트의 최상위 레벨)에서만 호출해야 한다.
(따라서 반복문이나 조건문 또는 중첩된 함수들 안에서 Hook을 호출하면 안 된다는 뜻임)
2. React 함수 컴포넌트에서만 Hook을 호출해야 한다.
(또는 직접 만든 커스텀 Hook에서만 호출 가능)
일반적인 JavaScript 함수에서 Hook을 호출하면 안됨.
- eslint-plugin-react-hooks 플러그인 : Hook의 규칙을 따르도록 강제해주는 플러그인.
( https://www.npmjs.com/package/eslint-plugin-react-hooks 페이지 참조)
Custom Hook 만들기
React에서 기본적으로 제공되는 Hook들 이외에 추가적으로 필요한 기능이 있다면 직접 Hook을 만들어서 사용할 수 있다.
커스텀 Hook을 만드는 이유는 여러 컴포넌트에서 반복적으로 사용되는 로직을 Hook으로 만들어 재사용하기 위함이다.
커스텀Hook은
- 이름이 use로 시작하고 내부에서 다른 Hook을 호출하는 하나의 자바스크립트 함수
이기만 하면 된다.
'스터디 > 처음 만난 React' 카테고리의 다른 글
처음 만난 리액트 - 10. Conditional Rendering (0) | 2024.04.02 |
---|---|
처음 만난 리액트 - 9. Handling Events (0) | 2024.04.01 |
처음 만난 리액트 - 7. State and Lifecycle (0) | 2024.03.21 |
처음 만난 리액트 - 6. Components and Props (0) | 2024.03.20 |
처음 만난 리액트 - 5. Rendering Elements (0) | 2024.03.19 |