리액트에서 Hook은 강력한 기능을 제공하지만, 이를 올바르게 사용하기 위해 반드시 지켜야 할 규칙이 있다.
이 규칙들은 리액트가 컴포넌트의 생명주기를 정확히 관리할 수 있도록 보장해 주는 역할을 한다.
Hook은 컴포넌트의 최상위 레벨에서만 호출해야 한다.
function MyComponent() {
const [name, setName] = useState("abc");
if (name !== "") {
// 잘못된 사용
useEffect( () => {
console.log("이름이 변경되었습니다.");
});
}
return <div>{name}</div>;
}
위 코드는 조건문 안에서 useEffects를 호출했기 때문에 잘못된 사용이다.
렌더링 시 조건에 따라 useEffect가 호출될 수도, 호출되지 않을 수도 있다.
이렇게 되면 Hook의 호출 순서가 달라지면서 문제가 발생할 수 있다.
function MyComponent() {
const [name, setName] = useState("abc");
useEffect( () => {
if (name !== "") {
console.log("이름이 변경되었습니다.");
}
});
return <div>{name}</div>;
}
조건문을 useEffect 내부로 옮겼다. 이제 useEffect는 항상 호출되므로 문제가 없다.
Hook은 일반 자바스크립트 함수에서 호출하면 안 된다. 반드시 리액트의 함수 컴포넌트 또는 커스텀 Hook 내부에서만 호출해야 한다.
// 일반 자바스크립트 함수에서 Hook을 호출하면 안 됨
function doSomething() {
const [state, setState] = useState(0); // 잘못된 사용
}
function MyComponent() {
const [state, setState] = useState(0);
return (
<button onClick={() => setState(state + 1)}>
{state}번 클릭했습니다.
</button>
);
}