useEffect
useState는 간단히 정리해서 "함수형 컴포넌트에서도 state를 사용할 수 있다!"였었다.
하지만 복잡한 로직을 위한 다양한 기능들을 살펴볼 필요가 있다.
useEffect는 그러한 기능들 중 하나로 useState가 기존의 방식을 대체하는 것 처럼 해당 기능 역시 componentDidUpdate와 componentDidMount를 대신한다고 봐도 좋다. 정확한 기능을 먼저 말하자면 리액트 컴포넌트가 렌더링될때 자동으로 해당 함수를 호출하게 되는데 특정 동작이 발생하면 특정 행동을 자동으로 실행한다.라고 말할 수 있다.
const UseEffectExample = () => {
const [test, setTest] = useState('initial value');
useEffect(() => {
console.log('렌더링!');
});
return(
<div>
<p>{test}</p>
<input onChange={(e) => {setTest(e.target.value)}} />
</div>
)
}
위 코드를 보자. 해당 컴포넌트가 렌더링 될 때마다 useEffect 함수가 실행되면서 콘솔에 로그를 남긴다.
기존의 state처럼, state의 값이 변경될 경우 렌더링을 새로 시도하기 때문에, input에 타자를 칠 때마다 로그가 찍히게 된다.
useEffect(() => {
console.log('렌더링!');
},[test]);
위의 코드와 같이 배열 형태로 특정 state를 넘기게 되면, 해당 state의 값이 변경될 때만 useEffect 함수가 호출되게 된다. 그러면 만약 여러개의 state에 대해서 여러개의 개별적인 동작을 실행시키고 싶다면?
useEffect(() => {
console.log('test state에 대해서만 호출!')
}, [test])
useEffect(() => {
console.log('test2 state에 대해서만 호출!')
}, [test2])
간단하다. 여러개의 useEffect를 설정하면 된다.
첫 렌더링에만 호출하기
그런데 만약 렌더링 될 때마다 호출되는 것이 아니라 처음에 렌더링 될 때 한번만 실행하고 싶은 경우에는 어떨까?
useEffect(() => {
console.log('첫 렌더링에만 호출')
}, [])
이렇게 할 경우 처음 렌더링 되는 한 번만 호출되고, 이후의 어떠한 렌더링에도 호출되지 않는다.
여기까지 useEffect에 대한 설명이다.
컴포넌트가 unmount될때 호출하기
컴포넌트가 렌더링 될 때마다 useEffect함수를 호출하는건 이제 알겠는데 그럼 컴포넌트가 unmount될때는 어떻게 해야할까? 사실 그런 경우에도 같은 구문을 사용하면 되지만 useEffect 함수에서 return을 해주면 된다.
useEffect(() => {
console.log('state가 변경될 때 마다 호출!');
return () => {
console.log('언마운트 시 호출!')
}
})
원래 없던 return이 추가되었다.
마지막 unmount에서만 호출하기
첫 렌더링에서만 useEffect를 호출하는 방법이 있습니다. 그럼 당연히 마지막 unmount에섬나 호출하는 방법도 있다. 방식도 같음. 두번째 인자를 빈 배열로 주면 된다.
const UseEffectExample = () => {
const [test, setTest] = useState('initial state');
useEffect(() => {
console.log('첫 렌더링에만 호출');
return () => {
console.log('마지막 언마운트 시 호출')
}
}, [])
return (
<div>
<p>{test}</p>
<input onChange={(e) => {setTest(e.target.value)}} />
</div>
)
}
function App() {
const [useEffectRender, setUseEffectRender] = useState(true);
return (
<div className="App">
{useEffectRender && <UseEffectExample />}
<button onClick={() => {setUseEffectRender(!useEffectRender)}}>마지막 언마운트 호출하기!</button>
</div>
);
}
export default App;
위의 코드는 마지막 언마운트 호출하기! 버튼을 누르면 useEffect가 설정된 UseEffectExample 컴포넌트가 unmount되도록 설정되어있다. 로그를 확인하면 알겠지만, 아무리 test state의 값을 변경해서 unmount/mount하더라도 로그는 찍히지 않는다. 하지만 버튼을 눌러서 해당 컴포넌트를 완전히 unmount시키면 로그가 찍히게 된다.