계속해서 React Hooks를 소개해드리겠습니다. 이번에 설명드릴 Hook(이하 훅)은 useEffect입니다.
앞서 소개한 useState만큼, 중요하고 자주 사용하는 훅입니다.
useEffect는 일반적으로 컴포넌트가 렌더링 될 때마다 작업을 수행할 수 있게 도움을 주는 훅입니다.
클래스형의 componentDidMount와 componentDidUpdate 기능과 유사한 기능을 제공합니다.
또한 return시 CleanUp을 해주는데 이때는 componentUnMount 기능을 합니다. 한번 자세하게 알아볼까요?
👩💻 useEffect?
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 같은 방식으로
useEffect(() => {
// 브라우저 API를 이용하여 문서 타이틀을 업데이트합니다.
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
위 코드는 React 공식 홈페이지에 있는 코드입니다.
useEffect는 렌더링 후 즉, 브라우저에 화면을 다 그린 후 동작합니다.
변화 감지 > 리렌더링 > useEffect 실행
쉽게 설명하자면 버튼을 클릭하면, setCount가 동작하여 count에 1을 더해주면 가상 돔은 변화를 감지하고 새롭게 렌더링을 해서 화면에는 You clicked 1 times가 나타날 것이고,그 다음 useEffect가 동작하여 홈페이지 제목이 You clicked 1 times로 변경됩니다.
(물론, 처음 사이트에 진입했을때도 화면이 그려진 뒤에 useEffect가 동작해서 처음엔 You clicked 0 times가 제목이 됩니다.)
🧐 좀 더 자세히 알아보기.
하지만, 맨 처음 사이트에 진입했을때, 딱 한번만 실행되길 바라는 경우도 있을 겁니다.
그럴 경우는 빈 배열을 두번째 매개번수로 넣어주면 됩니다. 무슨말인지 어렵죠? 코드와 함께 볼까요?
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 같은 방식으로
useEffect(() => {
// 브라우저 API를 이용하여 문서 타이틀을 업데이트합니다.
document.title = `You clicked ${count} times`;
}, []);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect 함수 맨 끝에 [] 빈 배열이 매개 변수로 들어가있습니다. 두번째 매개변수는 의존성 배열을 입력하는 곳입니다.
의존성 배열이 있다면 useEffect는 해당 배열안에 있는 값만 확인하여 해당 값에 변화가 있을 경우 useEffect를 실행하게 됩니다.
따라서 버튼으로 카운트 값을 올려도 페이지에서는 카운트가 올라가지만 타이틀에서는 0에서 변화가 없습니다.
왜 이렇게 되는지, 왜 의존성 배열을 사용하는지 알아봅시다.
🪢 의존성 배열?
의존성 배열은 쉽게 말해 해당 배열에 담긴 값들만 확인하겠다는 의미입니다.
useEffect를 의존성 배열 없이 사용하면 매번 새로운 렌더링 마다 동작합니다. 만약 Count 값에 변화가 없더라도 다른 요소때문에 렌더링이 되면 useEffect가 실행되기 때문에 비효율적이라고 할 수 있죠. Count에는 변화가 없는데 실행하니까요.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 같은 방식으로
useEffect(() => {
// 브라우저 API를 이용하여 문서 타이틀을 업데이트합니다.
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
코드를 위 같이 작성하면 count 값을 확인하고 count값에 변화가 있을때에만 useEffect가 실행 됩니다.
의존성 배열이 비여 있으면 첫 렌더링시 useEffect를 실행 후 다음번 부터는 의존할 값이 빈 배열이기 때문에 변화가 없는 것처럼 인식됩니다. 즉, 의존성을 속이게 됩니다. 그 때문에 처음 한번만 실행하고 그 뒤로는 실행하지 않게 됩니다.
🪧 클린업(Clean Up)
클린업은 쉽게 말해 componentUnMount 와 비슷한 역할을 하게 됩니다. 새롭게 렌더링 되기 전에 기존 렌더링을 지우고 나서 실행됩니다. 보기에는 렌더링이 지워질때 동작하는 것 처럼 보이지만, 실제로는 아래와 같이 클린업이 작동합니다.
새로운 렌더링 완료 -> 새 렌더링 이전 useEffect에 대해 클린업 -> useEffect 동작.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 같은 방식으로
useEffect(() => {
// 브라우저 API를 이용하여 문서 타이틀을 업데이트합니다.
document.title = `You clicked ${count} times`;
console.log("새 값 렌더링");
return () => {
console.log("이전 값 클린업");
}
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count+1)}>
Click me
</button>
</div>
);
}
콘솔에서는 첫 렌더링시 새 값 렌더링만 나타나게 되고 이후 버튼을 클릭해 새로운 렌더링이 되면 이전 값 클린업이 나타나고 다시 새 값 렌더링이 나타납니다.
왜 이렇게 동작하는 걸까요? 모든 함수는 렌더링 될때의 값을 가지고 있습니다.
⚠️ 여기서 부턴 제 생각이 담겨 있습니다. (정확하게 설명해주시면 더 감사합니다.)
모든 함수가 렌더링 될때의 값을 가지고 있는지 어떻게 아냐고 물어보신다면, 렌더링 될때의 값을 가지고 있기 때문에 이런 방법을 사용할 수 있다고 생각합니다. 이전에 이야기 했던 useState 훅을 아래와 같이 처리 할 수 있습니다.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 같은 방식으로
useEffect(() => {
// 브라우저 API를 이용하여 문서 타이틀을 업데이트합니다.
document.title = `You clicked ${count} times`;
console.log("새 값 렌더링");
return () => {
console.log("이전 값 클린업");
}
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(preValue => preValue+1)}>
Click me
</button>
</div>
);
}
버튼 onClick에 적용된 setCount함수를 봐주세요. count+1 대신 preValue 값을 불러와 해당값에 +1 을 리턴하는 함수를 넣었습니다.
한 번 동작해보세요. 이전과 차이없이 똑같이 동작하죠? 이것을 함수형 갱신(함수형 업데이트) 라고 표현합니다.
event 변수처럼 함수 실행시 전달하지 않고 함수 자체에 가지고 있어 동작하듯이, 여기서도 기존 값을 가지고 있어 그대로 받아와 원하는대로 업데이트를 해주는 것이라고 생각합니다. 이부분은 향후에 소개할 useReducer 훅으로 대체할 수 있습니다.
어느 용도로 활용해야 할지는 좀 더 공부를 해야겠지만 간단히 사용하더라도 많은 도움이 되는 함수인 useEffect 였습니다.
참조.
'Front-End > React' 카테고리의 다른 글
[React] Hooks - useReducer .07 (0) | 2023.02.03 |
---|---|
[React.js] Hooks - useRef .06 (0) | 2021.01.20 |
[React.js] Hooks - useState .04 (0) | 2020.12.20 |
[React.js] Check ES6 .03 (0) | 2020.12.10 |
[React.js] Start React! .02 (0) | 2020.12.08 |
삽질의 기록과 일상을 남기는 블로그입니다. 주로 React Native를 다룹니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!