훅스의 규칙
- 훅스를 사용할 때는 버그나 예기치 못한 동작을 방지하기 위해서 염두해 둬야 하는 몇 가지 규칙이 있다.
훅스는 컴포넌트의 영역 안에서만 작동한다
-
리액트 컴포넌트 내부에서만 훅스를 호출해야 한다. 그리고 커스텀 훅을 추가할 수도 있지만, 이런 커스텀 훅도 결국에는 컴포넌트에 추가되어야 한다.
-
훅스는 일반 자바스크립트가 아니라, 리액트 패턴이라는 점을 염두하라, 하지만 다른 라이브러리에서도 훅을 모델링하고 훅과 협력하는 경우가 많아졌다.
기능을 여러 훅으로 나누면 좋다
-
여러 기능이 있을 때 구독과 관련된 모든 기능을 한 효과에, 사운드와 관련한 모든 기능을 다른 효과에 넣었다. 이렇게 하니까 코드가 읽기 쉬워졌는데, 효과를 분리하면 다른 이점도 있다.
-
훅스가 순서대로 호출되기 때문에, 각 훅을 작게 유지하면 좋다. 호출되고 나면 리액트는 훅의 값을 배열에 저장하고 추적할 수 있게 해준다.
최상위 수준에서만 훅을 호출해야 한다
- 리액트 함수의 최상위 수준에서만 훅을 사용해야 한다. 조건문이나 루프, 내포된 함수 안에서 훅을 사용하면 안된다.
import {useEffect, useState} from "react";
function Counter() {
const [count, setCount] = useState(0);
if (count > 5) {
useEffect(() => {
...
});
}
-
useEffect
를if
문 안에서 사용하면count
값이 5보다 클때만 호출되므로 이로 인해서 배열 값이 사라진다. -
리액트에서는 이 배열안에 있는 효과의 위치가 중요하지, 효과가 어떻게 저장되어있는지는 중요하지 않다.
-
물론 조건에 따른 로직을 사용할 수 없다는 말은 아니다. 하지만 위와 같은 방식이 아니라, 아래와 같은 방식으로 조정해야 한다.
function Counter() {
const [count, setCount] = useState(0);
const [checked, toggle] = useState(
count => (count < 5) ? undefined : !count, (count < 5) ? undefined : ""
);
useEffect(() => {
});
}
-
훅 안에
if
문이나 루프나 다른 조건을 내포시키는 방식이다. -
조건 로직과 마찬가지로 비동기적인 동작도 훅 안에 넣을 필요가 있는데,
useEffect
는 첫 번째 인자로 프로미스가 아니라, 함수로 받는다. -
따라서
useEffect(async () => {})
와 같이 첫 번째 인자에async
함수를 넣을 수 없다. 하지만 아래와 같이 내포된 함수 안에서async
함수를 만들 수 는 있다.
useEffect(() => {
(
async () => {
await SomePromise();
})();
});
언제 리펙터링 하면 좋은가?
-
일반적으로
useMemo()
,useCallback()
,memo
가 과용되는 경향이 있다. -
리액트는 빨리 작동되도록 설계되었고 컴포넌트가 많이 렌더링 되도록 되어있다. 따라서 성능 최적화가 필요할 때만 위와같은 훅을 사용하면 된다.
-
useCallback()
이나useMemo()
가 좋은 생각인것 같아서 아무데서나 사용하면 오히려 성능이 떨어질 수 있다는 점을 주의하고 코드를 리펙터링할 때는 항상 목표를 설정하는 것이 중요하다.
참고 문헌
>> Home