August 14, 2025
๐ ์ถ์ ๋์ง ์๋ ํด๋ฆญ ์ด๋ฒคํธ: UX ํผ๋๊ณผ ๋ฐ์ดํฐ ๋ถ์ ์ค๋ฅ
JavaScript
React
UX
์๋ฌ์ฒ๋ฆฌ
์ปดํฌ๋ํธ
๋น๋๊ธฐ์ฒ๋ฆฌ
์ํคํ
์ฒ
์ฑ๋ฅ
ํ
์คํธ
Summary
ํด๋ฆญ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ ๋๋ก ๊ด๋ฆฌํ์ง ์์ผ๋ฉด UX ์ ํ, ๋ฐ์ดํฐ ๋ถ์ ์ค๋ฅ, ๋ฉ๋ชจ๋ฆฌ ๋์, ์๊ธฐ์น ์์ ๋์์ด ๋ฐ์ํ ์ ์์ต๋๋ค. useEffect
ํ
, ์ด๋ฒคํธ ์์, ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ํ
์คํ
์ ํตํด ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํฉ๋๋ค.
Why Wrong?
์ฌ์ฉ์ ์ธํฐ๋์ ์ถ์ ์ UX ๊ฐ์ ๊ณผ ๋ฐ์ดํฐ ๊ธฐ๋ฐ ์์ฌ ๊ฒฐ์ ์ ํ์์ ์ด์ง๋ง, ํด๋ฆญ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ ๋๋ก ๊ด๋ฆฌํ์ง ๋ชปํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
- UX ํผ๋: ํด๋ฆญ์ด ๋ฐ์ํ์ง๋ง ์๋ฌด๋ฐ ๋ฐ์์ด ์๊ฑฐ๋, ์์์น ๋ชปํ ๋์์ด ๋ฐ์ํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ํดํฉ๋๋ค.
- ๋ฐ์ดํฐ ๋ถ์ ์ค๋ฅ: ํด๋ฆญ ์ด๋ฒคํธ ์ถ์ ์คํจ๋ ๋ถ์ ํํ ๋ฐ์ดํฐ ๋ถ์์ผ๋ก ์ด์ด์ ธ ์๋ชป๋ ์์ฌ ๊ฒฐ์ ์ ์ด๋ํฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋์: ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ ๋๋ก ์ ๊ฑฐํ์ง ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ์ฌ ์ฑ๋ฅ ์ ํ๋ฅผ ์ ๋ฐํฉ๋๋ค.
- ์์์น ๋ชปํ ๋์: ์ปดํฌ๋ํธ๊ฐ unmount๋ ํ์๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ๋จ์์์ด ์๊ธฐ์น ์์ side effect๋ฅผ ๋ฐ์์ํฌ ์ ์์ต๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ ํนํ ๋์ ์ผ๋ก ์์ฑ๋๋ ์ปดํฌ๋ํธ, ๋น๋๊ธฐ ์์ , ๋ณต์กํ ์ํ ๊ด๋ฆฌ ์์คํ ์์ ํํ ๋ฐ์ํฉ๋๋ค.
How to Fix?
๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ ํตํด ํด๋ฆญ ์ด๋ฒคํธ ์ถ์ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
- ๋ช
์์ ์ธ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๊ด๋ฆฌ: ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋ ๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ถ๊ฐํ๊ณ , ์ธ๋ง์ดํธ๋ ๋ ์ ๊ฑฐํฉ๋๋ค. React์์๋
useEffect
ํ ์ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค. - ์ด๋ฒคํธ ์์ ํ์ฉ: ์ด๋ฒคํธ ๋ฒ๋ธ๋ง์ ์ด์ฉํ์ฌ ์์ ์์์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ฑ๋กํ๊ณ , ์ด๋ฒคํธ ๋ฐ์ ์ ํ๊ฒ ์์๋ฅผ ํ์ธํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ ๋์ ์ผ๋ก ์์ฑ๋๋ ์์์ ํจ๊ณผ์ ์ ๋๋ค.
- ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฐ๋: ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Redux, Zustand ๋ฑ)๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฒคํธ ๋ฐ์ ์ฌ๋ถ์ ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ์ค์ ์ง์ค์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ถ์ ํฉ๋๋ค.
- ํ ์คํ : ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ์์๋๋ก ์๋ํ๋์ง ์๋ํ๋ ํ ์คํธ๋ฅผ ํตํด ๊ฒ์ฆํฉ๋๋ค.
- ์ถ์ ์์คํ ์ ๊ฒ: ์ด๋ฒคํธ๊ฐ ๋ถ์ ์์คํ ์ ์ ์์ ์ผ๋ก ์ ๋ฌ๋๋์ง ์ฃผ๊ธฐ์ ์ผ๋ก ํ์ธํฉ๋๋ค.
Before Code (Bad)
import React, { useState } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
// ๋ฌธ์ : ์ปดํฌ๋ํธ๊ฐ unmount๋์ด๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์ ๊ฑฐ๋์ง ์์
document.addEventListener('click', () => {
console.log('Clicked!');
});
};
return (
<div>
<button onClick={handleClick}>Click me</button>
<p>Count: {count}</p>
</div>
);
}
export default MyComponent;
After Code (Good)
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
const handleClick = () => {
console.log('Clicked!');
};
document.addEventListener('click', handleClick);
// ์ปดํฌ๋ํธ๊ฐ unmount๋ ๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ๊ฑฐ
return () => {
document.removeEventListener('click', handleClick);
};
}, []); // ๋น ์์กด์ฑ ๋ฐฐ์ด: ์ปดํฌ๋ํธ ๋ง์ดํธ/์ธ๋ง์ดํธ ์์๋ง ์คํ
const handleButtonClick = () => {
setCount(count + 1);
};
return (
<div>
<button onClick={handleButtonClick}>Click me</button>
<p>Count: {count}</p>
</div>
);
}
export default MyComponent;
You Might Also Like
`useEffect` ํ
์ React ์ปดํฌ๋ํธ ๋ด์์ side effect๋ฅผ ์ํํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ, ์
๋ฐ์ดํธ, ์ธ๋ง์ดํธ๋ ๋ ํน์ ์ฝ๋๋ฅผ ์คํํ ์ ์๋๋ก ํด์ค๋๋ค.
https://react.dev/reference/react/useEffect
EventTarget.addEventListener() ๋ฉ์๋๋ ์ง์ ํ ์ ํ์ ์ด๋ฒคํธ๋ฅผ ๋์์ผ๋ก ์ค์ ํ๊ณ , ํด๋น ์ ํ์ ์ด๋ฒคํธ๊ฐ ๋์์์ ๋ฐ์ํ๋ฉด ์๋ฆผ์ ๋ฐ๋๋ก ํฉ๋๋ค.
https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener
EventTarget.removeEventListener() ๋ฉ์๋๋ `addEventListener()` ๋ฉ์๋๋ก ์ค์ ๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ ๊ฑฐํฉ๋๋ค.
https://developer.mozilla.org/ko/docs/Web/API/EventTarget/removeEventListener