일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- github
- Python
- 변수
- JavaScript
- hooks
- 선택자
- This
- react
- ES5+
- ES6+
- 햇소
- API
- object
- next.js
- 함수
- html5
- DOM
- dev
- 우아한테코톡
- es6
- array
- gitCLI
- learn next.js
- JS
- git
- developerlife
- 최적화
- CSS
- hatso
- AI
- Today
- Total
codinghatso
React Hook이란? 본문
Hook이란?
React 16.8에 새로 추가된 기능. Hook은 class를 작성하지 않고도 state와 다른 react의 기능들을 사용할 수 있도록 해준다.
Hook은 특별한 함수이다.
예를 들어 "useState"(Hook함수)는 state를 함수 컴포넌트 안에서 사용할 수 있게 해 줍니다.
기존 에는 state를 추가하고 싶을 때 클래스 컴포넌트로 바꾸곤 했습니다.
하지만 이제 함수 컴포넌트 안에서 Hook을 이용하여 state를 사용할 수 있습니다.
Hook의 규칙
- 최상위(at the Top Level)에서만 Hook을 호출해야 합니다.
- 반복문, 조건문 혹은 중첩된 함수 내에서 Hook을 호출하지 마세요.
- 이 규칙을 따르면 컴포넌트가 렌더링 될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장됩니다.
- 오직 React 함수 내에서 Hook을 호출해야 합니다.
- Hook을 일반적인 JavaScript 함수에서 호출하지 마세요.
- React 함수 컴포넌트에서 Hook을 호출하세요.
- Custom Hook에서 Hook을 호출하세요.
Hook의 규칙을 강제하는 eslint-plugin-react-hooks라는 ESLint플러그인을 출시했고, 이 플러그인은 Create React App에 기본적으로 포함되어 있습니다.
npm install eslint-plugin-react-hooks --save-dev
// ESLint 설정 파일
{
"plugins": [
// ...
"react-hooks"
],
"rules": {
// ...
"react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
"react-hooks/exhaustive-deps": "warn" // Checks effect dependencies
}
}
설명
한 컴포넌트에서 State나 Effect Hook을 여러 개 사용할 수도 있습니다.
function Form() {
// 1. name이라는 state 변수를 사용하세요.
const [name, setName] = useState('Mary');
// 2. Effect를 사용해 폼 데이터를 저장하세요.
useEffect(function persistForm() {
localStorage.setItem('formData', name);
});
// 3. surname이라는 state 변수를 사용하세요.
const [surname, setSurname] = useState('Poppins');
// 4. Effect를 사용해서 제목을 업데이트합니다.
useEffect(function updateTitle() {
document.title = name + ' ' + surname;
});
// ...
}
React가 Hook의 호출되는 순서에 의존한다는 것입니다.
모든 렌더링에서 Hook의 호출 순서는 같기 때문에 예시가 올바르게 동작할 수 있습니다.
// ------------
// 첫 번째 렌더링
// ------------
useState('Mary') // 1. 'Mary'라는 name state 변수를 선언합니다.
useEffect(persistForm) // 2. 폼 데이터를 저장하기 위한 effect를 추가합니다.
useState('Poppins') // 3. 'Poppins'라는 surname state 변수를 선언합니다.
useEffect(updateTitle) // 4. 제목을 업데이트하기 위한 effect를 추가합니다.
// -------------
// 두 번째 렌더링
// -------------
useState('Mary') // 1. name state 변수를 읽습니다.(인자는 무시됩니다)
useEffect(persistForm) // 2. 폼 데이터를 저장하기 위한 effect가 대체됩니다.
useState('Poppins') // 3. surname state 변수를 읽습니다.(인자는 무시됩니다)
useEffect(updateTitle) // 4. 제목을 업데이트하기 위한 effect가 대체됩니다.
// ...
Hook의 호출 순서가 렌더링 간에 동일하다면 React는 지역적인 state를 각 Hook에 연동시킬 수 있습니다.
하지만 Hook을 조건문 안에서 호출한다면 어떤 일이 일어날까요?
// 🔴 조건문에 Hook을 사용함으로써 첫 번째 규칙을 깼습니다
if (name !== '') {
useEffect(function persistForm() {
localStorage.setItem('formData', name);
});
}
name !== '' 조건은 첫 번째 렌더링에서 true 기 때문에 Hook은 동작합니다.
하지만 사용자가 그다음 렌더링에서 폼을 초기화하면서 조건을 false로 만들 겁니다.
렌더링 간에 Hook을 건너뛰기 때문에 Hook 호출 순서가 달라집니다.
useState('Mary') // 1. name state 변수를 읽습니다. (인자는 무시됩니다)
// useEffect(persistForm) // 🔴 Hook을 건너뛰었습니다!
useState('Poppins') // 🔴 2 (3이었던). surname state 변수를 읽는 데 실패했습니다.
useEffect(updateTitle) // 🔴 3 (4였던). 제목을 업데이트하기 위한 effect가 대체되는 데 실패했습니다.
Hook을 건너뛰면서 다음에 호출되는 Hook의 순서가 하나씩 밀리면서 버그를 발생시키게 됩니다.
이것이 컴포넌트 최상위(the top of level)에서 Hook이 호출되어야만 하는 이유입니다.
조건부로 effect를 실행하기를 원한다면, 조건문을 Hook 내부에 넣을 수 있습니다.
useEffect(function persistForm() {
// 👍 더 이상 첫 번째 규칙을 어기지 않습니다
if (name !== '') {
localStorage.setItem('formData', name);
}
});
제공된 lint 규칙을 활용한다면 이 문제에 대해 걱정할 필요는 없습니다.
정리
Hook은 함수 컴포넌트 안에서 state를 사용할 수 있게 해 줍니다.
하나의 컴포넌트에서 여러 개 사용가능합니다.
모든 렌더링에서 Hook의 호출 순서는 같습니다.
Hook을 사용할 때 2가지 규칙을 지켜야 하며, 규칙을 지키지 않았을 때 버그가 발생할 수 있습니다.
'WEB > React' 카테고리의 다른 글
useContext - React Hooks (0) | 2023.11.03 |
---|---|
useRef - React Hooks (0) | 2023.11.01 |
useEffect - React Hooks (0) | 2023.11.01 |
useState - React Hooks (2) | 2023.10.23 |
학습 체크리스트 (0) | 2023.10.20 |