왜 Hooks는 컴포넌트의 최상위 레벨에서 호출해야 하나요?
2023. 12. 29. 21:04ㆍReact
728x90
반응형
hook을 작성할 때는 반드시 컴포넌트의 최상위 레벨 혹은 커스텀 훅 안에서만 작성할 수 있다.
즉, 조건문, 반복문, 함수 내부에서는 hook을 호출할 수 없다.
왜 이런 규칙이 생겼는지 알아보자!!
🔗 참고한 글
useState를 호출하는 코드를 보면, 인자로 초기값만을 전달하고 있다.
const [index, setIndex] = useState(0);
어떤 state 변수를 참조하는 지에 대한 정보는 받지 않는다!
이렇게 useState
에 전달되는 식별자가 없는데, 어떤 state 변수를 반환할지 어떻게 아는 것일까?? 😲
hook은 동일한 컴포넌트의 모든 렌더링에서 안정적인 호출 순서에 의존한다.
최상위 수준에서만 hook을 호출한다는 규칙을 따르면 hook은 항상 같은 순서로 호출된다.
이렇게 매 렌더링마다 동일한 순서로 호출되는
모든 hook은 컴포넌트마다 배열로 관리된다.
그리고
hook이 호출되는 순서에 따라서 렌더링 간에 어떤 hook인지 파악한다.
아래의 예제는 useState
가 내부적으로 어떻게 작동하는지 간략화한 함수이다.
let componentHooks = []; // 컴포넌트의 모든 훅을 저장하는 배열
let currentHookIndex = 0; // 현재 처리 중인 훅의 인덱스
function useState(initialState) {
let pair = componentHooks[currentHookIndex];
if (pair) {
// 첫 번째 렌더링이 아닐 경우
// pair를 반환하고 다음 훅 호출을 위해 index를 증가한다.
currentHookIndex++;
return pair;
}
// 첫 번째 렌더링이라면, componentHooks[0]에 상태 pair를 생성해서 저장한다.
pair = [initialState, setState];
function setState(nextState) {
// 상태 변경을 요청하면, 새 값을 현재 pair에 저장한다.
pair[0] = nextState;
updateDOM();
}
// 다음 렌더링을 위해 현재 pair를 hooks 배열에 저장하고,
componentHooks[currentHookIndex] = pair;
// 다음 훅 호출을 위해 index를 증가한다.
currentHookIndex++;
return pair;
}
function updateDOM() {
// 현재 훅 인덱스를 리셋한다.
currentHookIndex = 0;
let output = Gallery();
// DOM을 출력 내용과 일치하도록 업데이트한다.
nextButton.onclick = output.onNextClick;
header.textContent = output.header;
moreButton.onclick = output.onMoreClick;
// ...
}
let nextButton = document.getElementById('nextButton');
let header = document.getElementById('header');
let moreButton = document.getElementById('moreButton');
// ...
// UI를 초기 상태와 일치하게 만든다.
updateDOM();
즉, 첫 번째 setState는 첫 번째 state 변수를 변경하고
두 번째 setState는 두 번째 state 변수를 변경한다.
이런식으로 몇 번째에 호출된 hook인지에 따라서 값을 식별하므로 순서가 보장되어야 하는 것!
그리고 그 순서를 보장하기 위해 조건문이나 반복문, 중첩된 함수 내부에서 hook을 호출하지 않고,
컴포넌트의 최상위 레벨에서만 작성하는 것이다. 😁
728x90
반응형
'React' 카테고리의 다른 글
[React] useFormState, useFormStatus (1) | 2024.02.12 |
---|---|
[React] useRef, forwardRef, useImperativeHandle (1) | 2023.12.12 |
[Redux] Redux, React Redux, Redux DevTools (1) | 2023.10.03 |