React : useEffect 의 의존성 배열 활용법
React의 useEffect
에서 의존성 배열([]
)에는 효과(Effect)가 다시 실행되기 위해 어떤 값(상태, 함수, props 등)이 변경되어야 하는지를 명시합니다. 일반적으로 다음과 같은 요소들이 의존성 배열에 포함됩니다:
1. 상태(state)
useState
로 관리하는 상태가 useEffect
에서 사용되는 경우, 해당 상태를 의존성 배열에 포함해야 합니다. 상태 값이 변경되면 useEffect
가 다시 실행됩니다.
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`Count has changed: ${count}`);
}, [count]); // count가 변경될 때마다 실행
2. Props
부모 컴포넌트로부터 전달받은 props를 사용하는 경우, 의존성 배열에 포함해야 합니다. props
가 변경될 때 useEffect
가 다시 실행됩니다.
const Child = ({ title }) => {
useEffect(() => {
console.log(`Title has changed: ${title}`);
}, [title]); // title이 변경될 때마다 실행
return <div>{title}</div>;
};
3. 함수
컴포넌트 내부에서 정의된 함수가 useEffect
에서 사용된다면, 의존성 배열에 해당 함수 참조를 포함해야 합니다. 특히 useCallback
으로 메모이제이션된 함수라면, 최신 로직을 반영하기 위해 의존성 배열에 포함해야 합니다.
const fetchData = useCallback(() => {
console.log("Fetching data...");
}, []);
useEffect(() => {
fetchData();
}, [fetchData]); // fetchData가 변경될 때마다 실행
4. Context 값
useContext
로 가져온 컨텍스트 값이 useEffect
에서 사용된다면, 해당 컨텍스트 값을 의존성 배열에 포함해야 합니다. 컨텍스트 값이 변경될 때 useEffect
가 다시 실행됩니다.
const ThemeContext = React.createContext();
const MyComponent = () => {
const theme = useContext(ThemeContext);
useEffect(() => {
console.log(`Theme changed: ${theme}`);
}, [theme]); // theme 값이 변경될 때마다 실행
};
5. Memoized 값
useMemo
를 통해 계산된 값이 useEffect
에서 사용된다면, 해당 값을 의존성 배열에 포함해야 합니다. 계산된 값이 변경되면 useEffect
가 다시 실행됩니다.
const computedValue = useMemo(() => calculateSomething(dep1, dep2), [dep1, dep2]);
useEffect(() => {
console.log(`Computed value changed: ${computedValue}`);
}, [computedValue]); // computedValue가 변경될 때마다 실행
6. 외부 변수
컴포넌트 외부에서 정의된 변수나 객체를 사용하는 경우, 해당 참조를 의존성 배열에 포함해야 최신 값을 참조할 수 있습니다.
let externalValue = 0;
const MyComponent = () => {
useEffect(() => {
console.log(`External value: ${externalValue}`);
}, [externalValue]); // 외부 값이 변경될 때마다 실행
};
의존성 배열에 포함하지 않아야 할 것들
1. 불필요한 포함: 의존성 배열에 포함하지 않아도 되는 값(정적인 값, 변하지 않는 값 등)을 포함하면 불필요한 실행이 발생합니다.
const staticValue = 42;
useEffect(() => {
console.log("This runs unnecessarily");
}, [staticValue]); // staticValue는 변하지 않으므로 포함하지 않아도 됨
2. useEffect 내부에서 선언된 변수: 내부에서 선언된 변수는 의존성 배열에 추가하지 않아도 됩니다.
useEffect(() => {
const localValue = calculateValue();
console.log(localValue);
}, []); // localValue는 의존성 배열에 추가하지 않아도 됨
의존성 배열 관리 시 주의사항
- 의존성을 누락하지 말 것:
eslint-plugin-react-hooks
와 같은 도구를 사용하여 의존성 배열을 자동으로 관리하도록 설정하세요.- 의존성을 누락하면 최신 상태나 로직이 반영되지 않아 의도하지 않은 동작이 발생할 수 있습니다.
- 불필요한 리렌더링 방지:
- 의존성 배열에 불필요한 값을 포함하면
useEffect
가 빈번하게 실행되어 성능 문제가 발생할 수 있습니다. - 꼭 필요한 값만 포함하세요.
- 의존성 배열에 불필요한 값을 포함하면
결론
useEffect
의 의존성 배열에는 다음과 같은 값들을 포함해야 합니다:
useState
로 관리되는 상태- 부모 컴포넌트로부터 전달받은 props
useCallback
이나 메모이제이션된 함수useContext
로 가져온 컨텍스트 값useMemo
로 계산된 값
이를 통해 React가 필요한 시점에만 useEffect
를 실행하도록 관리할 수 있습니다.