
Detail ํ์ด์ง ์์ ๋ ธ๋ ๋ฐ์ค ํ๋ ๋ง๋ค๊ณ , Detail ํ์ด์ง ๋ฐฉ๋ฌธ ํ 2์ด ํ์ ๋ฐ์ค๊ฐ ์ฌ๋ผ์ง๊ฒ ํด๋ณด์ญ์์ค.
ํ: ๋์ ์ธ UI ์ด๋ป๊ฒ ๋ง๋ ๋ค๊ณ ํ๋์? ๐ค
์ปดํฌ๋ํธ๋ ์ธ์์ด ์์ต๋๋ค! ์ฌ๋์ฒ๋ผ ํ์ด๋๊ณ , ์ด๋ค๊ฐ, ์ฃฝ์ต๋๋ค.
์ปดํฌ๋ํธ ์ธ์์ ์ค๊ฐ์ค๊ฐ์ ๊ฐ์ญํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค!
์ด๋ฐ ๊ฐ์ญ์ ๊ฐ๊ณ ๋ฆฌ(hook)๋ฅผ ๋ฌ์์ ํฉ๋๋ค!
class Detail2 extends React.Component {
componentDidMount(){
//Detail2 ์ปดํฌ๋ํธ๊ฐ ๋ก๋๋๊ณ ๋์ ์คํํ ์ฝ๋
}
componentDidUpdate(){
//Detail2 ์ปดํฌ๋ํธ๊ฐ ์
๋ฐ์ดํธ ๋๊ณ ๋์ ์คํํ ์ฝ๋
}
componentWillUnmount(){
//Detail2 ์ปดํฌ๋ํธ๊ฐ ์ญ์ ๋๊ธฐ์ ์ ์คํํ ์ฝ๋
}
}
import {useState, useEffect} from 'react';
function Detail(){
useEffect(() => {
//์ฌ๊ธฐ์ ์ ์ฝ๋๋ ์ปดํฌ๋ํธ ๋ก๋ & ์
๋ฐ์ดํธ ๋ง๋ค ์คํ๋จ
console.log('์๋
')
});
return (
// ์ปดํฌ๋ํธ ๋ด์ฉ
)
}
import {useState, useEffect} from 'react';
function Detail(){
useEffect(() => {
console.log('์๋
')
});
let [count, setCount] = useState(0)
return (
<button onClick={() => { setCount(count+1) }}>๋ฒํผ</button>
)
}
์ฐธ๊ณ : <React.StrictMode> ํ๊ทธ๊ฐ ์์ผ๋ฉด ๊ฐ๋ฐ ๋ชจ๋์์ 2๋ฒ ์ถ๋ ฅ๋ฉ๋๋ค (๋๋ฒ๊น
์ฉ)
๋ง์ต๋๋ค! useEffect ๋ฐ๊นฅ์ ์ ์ด๋ ์ปดํฌ๋ํธ mount & update ์ ์คํ๋ฉ๋๋ค.
useEffect ๋ฐ์ ์ฝ๋ ์์ฑ:
function Detail(){
(๋ฐ๋ณต๋ฌธ 10์ต๋ฒ ๋๋ฆฌ๋ ์ฝ๋) // โ html ๋ ๋๋ง ์ ์ ์คํ
return (์๋ต)
}
โ ๋ฐ๋ณต๋ฌธ ์๋ฃ ํ HTML ๋ณด์ฌ์ค
useEffect ์์ ์ฝ๋ ์์ฑ:
function Detail(){
useEffect(() => {
(๋ฐ๋ณต๋ฌธ 10์ต๋ฒ ๋๋ฆฌ๋ ์ฝ๋) // โ html ๋ ๋๋ง ํ์ ์คํ
});
return (์๋ต)
}
โ HTML ๋จผ์ ๋ณด์ฌ์ฃผ๊ณ ๋ฐ๋ณต๋ฌธ ์คํ
๋ชฉ์ : HTML ๋ ๋๋ง์ ๋น ๋ฅด๊ฒ ํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์ ! โก
1. ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ (mount + update ์ ์คํ)
useEffect(() => {
console.log('์ปดํฌ๋ํธ ๋ ๋๋ง๋จ');
});
2. ํ ๋ฒ๋ง ์คํ (mount ์์๋ง)
useEffect(() => {
console.log('์ปดํฌ๋ํธ ์ฒ์ ๋ ๋๋ง๋จ');
}, []); // ๋น ๋ฐฐ์ด์ด ํต์ฌ!
3. ํน์ ๊ฐ ๋ณ๊ฒฝ ์์๋ง ์คํ
useEffect(() => {
console.log('count๊ฐ ๋ณ๊ฒฝ๋จ');
}, [count]); // count ๋ณ๊ฒฝ ์์๋ง ์คํ
4. cleanup ํจ์ (unmount ์ ์คํ)
useEffect(() => {
const timer = setInterval(() => {
console.log('1์ด๋ง๋ค ์คํ');
}, 1000);
return () => {
clearInterval(timer); // ์ปดํฌ๋ํธ ์ ๊ฑฐ ์ ํ์ด๋จธ ์ ๋ฆฌ
};
}, []);
1. API ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
function ProductList() {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('/api/products')
.then(response => response.json())
.then(data => {
setProducts(data);
setLoading(false);
})
.catch(error => {
console.error('๋ฐ์ดํฐ ๋ก๋ฉ ์คํจ:', error);
setLoading(false);
});
}, []); // ์ปดํฌ๋ํธ ๋ง์ดํธ ์ ํ ๋ฒ๋ง
if (loading) return <div>๋ก๋ฉ ์ค...</div>;
return (
<div>
{products.map(product => (
<div key={product.id}>{product.name}</div>
))}
</div>
);
}
2. ํ์ด๋จธ ๊ตฌํ
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
// cleanup: ์ปดํฌ๋ํธ ์ ๊ฑฐ ์ ํ์ด๋จธ ์ ๋ฆฌ
return () => clearInterval(interval);
}, []);
return <div>{seconds}์ด ๊ฒฝ๊ณผ</div>;
}
3. ์๋์ฐ ์ด๋ฒคํธ ๋ฆฌ์ค๋
function ScrollTracker() {
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => {
setScrollY(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
// cleanup: ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ๊ฑฐ
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
return <div>์คํฌ๋กค ์์น: {scrollY}px</div>;
}
1. ์์กด์ฑ ๋ฐฐ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๊ธฐ
// โ ์๋ชป๋ ์: ๋ฌดํ ๋ฃจํ ์ํ
useEffect(() => {
setData(processData(props.rawData));
}); // ์์กด์ฑ ๋ฐฐ์ด ์์
// โ
์ฌ๋ฐ๋ฅธ ์: props.rawData ๋ณ๊ฒฝ ์์๋ง ์คํ
useEffect(() => {
setData(processData(props.rawData));
}, [props.rawData]);
2. useCallback๊ณผ ํจ๊ป ์ฌ์ฉ
function Parent() {
const [count, setCount] = useState(0);
// useCallback์ผ๋ก ํจ์ ๋ฉ๋ชจ์ด์ ์ด์
const fetchData = useCallback(async () => {
const response = await fetch(`/api/data/${count}`);
return response.json();
}, [count]);
return <Child onFetch={fetchData} />;
}
function Child({ onFetch }) {
useEffect(() => {
onFetch().then(data => console.log(data));
}, [onFetch]); // onFetch๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ์คํ
}
1. ๋ฌดํ ๋ฃจํ
// โ ๋ฌธ์ : ๋ฌดํ ๋ฃจํ ๋ฐ์
function BadComponent() {
const [data, setData] = useState([]);
useEffect(() => {
setData([...data, 'new item']); // data ๋ณ๊ฒฝ โ ๋ฆฌ๋ ๋๋ง โ useEffect ์ฌ์คํ
}, [data]);
}
// โ
ํด๊ฒฐ: ํจ์ํ ์
๋ฐ์ดํธ ์ฌ์ฉ
function GoodComponent() {
const [data, setData] = useState([]);
useEffect(() => {
setData(prev => [...prev, 'new item']);
}, []); // ๋น ๋ฐฐ์ด๋ก ํ ๋ฒ๋ง ์คํ
}
2. Memory Leak ๋ฐฉ์ง
function Component() {
useEffect(() => {
const subscription = subscribe();
// ๋ฐ๋์ cleanup ํจ์์์ ์ ๋ฆฌํ๊ธฐ
return () => {
subscription.unsubscribe();
};
}, []);
}
๋ ธ๋ ๋ฐ์ค๊ฐ 2์ด ํ ์ฌ๋ผ์ง๊ฒ ํ๋ ค๋ฉด:
// ํํธ ๊ตฌ์กฐ
function Detail() {
const [showBox, setShowBox] = useState(true);
useEffect(() => {
// 2์ด ํ ๋ฐ์ค ์จ๊ธฐ๊ธฐ
setTimeout(() => {
setShowBox(false);
}, 2000);
}, []);
return (
<div>
{showBox && <div className="yellow-box">๋
ธ๋ ๋ฐ์ค</div>}
{/* ๋๋จธ์ง ๋ด์ฉ */}
</div>
);
}