잘못된 예시
🖥️ jsx
// ❌ 일반 함수에서 Hook 사용
function normalFunction() {
const [state, setState] = useState(0); // 이렇게 하면 안됨!
}
// ❌ 클래스 컴포넌트의 메서드에서 Hook 사용
class Component extends React.Component {
render() {
const [state, setState] = useState(0); // 이렇게 하면 안됨!
return <div>{state}</div>;
}
}
올바른 예시
🖥️ jsx
// ✅ 함수 컴포넌트에서 Hook 사용
function ExampleComponent() {
const [state, setState] = useState(0);
return <div>{state}</div>;
}
// ✅ Custom Hook에서 Hook 사용
function useCustomHook() {
const [state, setState] = useState(0);
return state;
}
1. Hook의 이름 규칙
2. 의존성 배열 관리
🖥️ jsx
function ExampleComponent({ userId }) {
// ✅ 의존성 배열에 필요한 값 포함
useEffect(() => {
fetchUserData(userId);
}, [userId]); // userId가 변경될 때만 실행
}
3. Hook 합성
4. 조건부 실행
Hook 자체는 조건부로 실행할 수 없지만, Hook 내부의 로직은 조건부로 실행할 수 있.
jsx
// ✅ Hook 내부에서 조건부 로직 사용
function ExampleComponent({ condition }) {
useEffect(() => {
if (condition) {
// 조건부 로직
}
}, [condition]);
}
React는 Hook의 호출 순서에 의존하여 각 Hook의 상태를 추적한다.
컴포넌트가 렌더링될 때마다 Hook은 항상 동일한 순서로 호출되어야 한다.
조건문 안에서 Hook을 사용하면 조건에 따라 Hook이 호출되지 않을 수 있어,
호출 순서가 깨지고 예기치 않은 버그가 발생할 수 있다.
잘못된 사용 예시
🖥️ jsx
function ExampleComponent({ condition }) {
// ❌ 잘못된 사용: 조건에 따라 Hook 호출 순서가 변경됨
if (condition) {
const [state, setState] = useState(0);
}
const [count, setCount] = useState(0);
// 이 경우 condition이 false가 되면 첫 번째 useState가 호출되지 않아
// count의 상태가 엉뚱한 값을 참조할 수 있음
}
올바른 사용 예시
🖥️ jsx
function ExampleComponent({ condition }) {
// ✅ 올바른 사용: Hook은 항상 최상위에서 호출
const [state, setState] = useState(0);
const [count, setCount] = useState(0);
// 조건부 로직은 Hook 호출 후에 처리
if (condition) {
// state 값을 사용하는 로직
}
}
3. useEffect에서의 조건부 처리
조건부 로직이 필요한 경우, useEffect 내부에서 처리하거나 Hook 호출 후에 처리해야 한다.
🖥️ jsx
function ExampleComponent({ condition }) {
const [data, setData] = useState(null);
// ✅ 올바른 사용: useEffect 내부에서 조건 처리
useEffect(() => {
if (condition) {
// 조건이 참일 때만 실행되는 로직
fetchData().then(result => setData(result));
}
}, [condition]);
// 또는 Hook 사용 후 조건부 렌더링
return (
<div>
{condition && <div>{data}</div>}
</div>
);
}
4. Custom Hook에서의 규칙
Custom Hook을 만들 때도 동일한 규칙이 적용된다.
jsx
// ✅ 올바른 Custom Hook 구현
function useCustomHook(condition) {
const [state, setState] = useState(null);
useEffect(() => {
if (condition) {
// 조건부 로직
}
}, [condition]);
return state;
}
// ❌ 잘못된 Custom Hook 구현
function useCustomHook(condition) {
if (condition) {
// 이렇게 하면 안 됨!
const [state, setState] = useState(null);
}
return null;
}
5. ESLint 규칙
이러한 Hook 규칙을 지키기 위해 React는 eslint-plugin-react-hooks라는 ESLint 플러그인을 제공한다. 이 플러그인은 Hook의 잘못된 사용을 감지하고 경고해준다.
➡️ 이러한 규칙들은 React 컴포넌트의 예측 가능성과 안정성을 보장하기 위해 매우 중요하다. Hook의 호출 순서가 보장되어야 React가 각 Hook의 상태를 올바르게 추적하고 관리할 수 있다.