sideEffect
프로그래밍에서 side effect 란 함수가 함수 내부의 값 외에 외부의 값을 읽어오거나, 수정하는 행위를 의미한다. side effect는 함수의 동작 결과를 예측하기 어렵게 만들기에 일반적으로는 기피해야 하는 대상이지만 side effect를 하나도 발생시키지 않고 프로그래밍을 할 수는 없기 때문에 useEffect hook을 사용하는것이다.프론트엔드 개발에서도 마찬가지로 side effect를 발생시켜야 하는 순간이 있다. 가장 흔한 사례로는 Data Fetching, DOM 접근 및 조작, 구독 등의 행위가 있다.
useEffect
const App = () => {
const doSideEffect = () => {
// do some side effect
};
doSideEffect();
return <h1>Hello World</h1>;
};
위와 같이 side effect를 발생시키게 되면 두 가지 문제가 발생한다.
1. side effect가 렌더링을 blocking
2. 매 렌더링마다 side effect가 수행
이 두가지 문제점을 해결하기 위해 useEffect를 사용하면 된다.
useEffect(콜백 함수);
import { useEffect } from 'react';
const App = () => {
// 코드 생략
useEffect(doSideEffect);
return <h1>Hello, Wecoder</h1>;
};
side effect를 발생시키는 함수를 바로 호출하는 것이 아니라 useEffect의 인자로 전달한다. 위와 같이 useEffect의 인자로 전달된 콜백 함수는 곧바로 호출되는 것이 아니라 모든 렌더링이 완료된 후에 호출된다. 즉 렌더링을 blocking 하지 않고 side effect를 발생시킬 수 있게 되는 것이다.
useEffect(콜백 함수, 의존성 배열);
예시
import { useEffect } from 'react'
// 사용법
useEffect(콜백 함수, 의존성 배열);
// 1. 의존성 배열이 전달되지 않았으므로 매 렌더링마다 side effect가 실행된다
useEffect(() => {
// side effect
});
// 2. 첫 번째 렌더링 이후에 side effect를 실행하고
// 그 이후에는 value 값이 변했을 때만 실행한다.
useEffect(() => {
// side effect
}, [value]);
// 3. 첫 번째 렌더링 이후에 side effect를 실행하고
// 그 이후에는 value1, value2 중 하나라도 변하면 side effect를 실행한다.
useEffect(() => {
// side effect
}, [value1, value2]);
useEffect(() => {
const countTime = () => {
console.log('100ms가 지났습니다.');
};
setInterval(countTime, 100);
}, []);
side effect는 setInterval 함수를 이용해서 100ms마다 countTime 함수가 호출되도록 하고 있다. useEffect의 의존성 배열에 빈 배열이 전달되었으므로 첫 번째 렌더링 이후에 side effect가 실행된다. 그런데 이 side effect를 clean up 해주지 않는다면 컴포넌트가 unmount 되는 경우 등 setInterval을 통한 구독이 필요 없어진 상황에서도 계속해서 콘솔이 출력되고 있을 것이다. 이를 해결하기 위해서 clean up effect를 사용한다.
useEffect(() => {
const countTime = () => {
console.log('100ms가 지났습니다.');
};
let clear = setInterval(countTime, 100);
return () => {
clearTimeout(clear);}
}, []);
useEffect는 clean up 함수를 두가지 경우에 호출해준다.