
๐ useEffect
useEffect()๋ ํ์ด์ง์ ๋ง์ดํธ, ์ธ๋ง์ดํธ, ์ ๋ฐ์ดํธ ์ ์์ ์ ์ค์ ํ๋ค.
์ฉ์ด | ์ค๋ช |
Mount | ์ปดํฌ๋ํธ๊ฐ ํ์ด์ง์ ๋ํ๋จ |
unMount | ์ปดํฌ๋ํธ๊ฐ ํ์ด์ง์์ ์ฌ๋ผ์ง |
์ ๋ฐ์ดํธ๋ useEffect() ํน์ ๊ฐ์ ์์กดํ์ฌ ํด๋น ๊ฐ์ด ๋ณ๊ฒฝ, ์คํ๋๋ฉด ํด๋น useEffect()๋ฅผ ์ฌ์คํํ๋ค.
useEffect()์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
useEffect(()=> {
// ๋ง์ดํธ ์๋ฃ ํ ์คํํ ์ฝ๋
return () => {
// ์ธ๋ง์ดํธ ์๋ฃ ํ ์คํํ ์ฝ๋
}
}, [dependencies])
dependencies์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ์ธ๋ง์ดํธ๊ฐ ์ผ์ด๋๋ฉด์ return()์ ํตํด ๊ธฐ์กด ์์ ์ ํด์ ํ๊ณ ๋ค์ ๋ง์ดํธ ์ํจ๋ค.
๐ป Code
๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ค.
๐ EffectComponent.tsx
import React, { useEffect, useState } from 'react'
import { PopupComponent } from './PopupComponent'
export function EffectComponent(): JSX.Element {
const [isOpen, setIsOpen] = useState<boolean>(false)
// !: ๋ถ์ ์ฐ์ฐ์ boolํ์
์ ๊ฐ์ ๋ฐ๋๊ฐ์ผ๋ก ๋ณํํฉ๋๋ค.
// true -> false
// false -> true
const handlerBoolean = () => setIsOpen(!isOpen)
return (
<div style={{ textAlign: 'center' }}>
/* ์ผํญ ์ฐ์ฐ์
//์กฐ๊ฑด ? ์กฐ๊ฑด์ด true์ผ ๋ ๋ฐํ๊ฐ : ์กฐ๊ฑด์ด false์ผ ๋ ๋ฐํ๊ฐ
/*
<button onClick={handlerBoolean}>{isOpen ? '๋ซ๊ธฐ' : '์ด๊ธฐ'}</button>
/* ๋
ผ๋ฆฌ๊ณฑ(&&)
// ์ผ์ชฝ๋ถํฐ ๊ฐ์ ๊ฒ์ฌํ์ฌ true๊ฐ์ ๊ฐ์ง๋ฉด ๋ง์ง๋ง ๊ฐ์ ๋ฐํ
*/
{isOpen && <PopupComponent />}
</div>
)
}
isOpen์ ์ํ์ ๋ฐ๋ผ์ ์ปดํฌ๋ํธ(<PopupComponent/>)๋ฅผ ํ์ด์ง์ ๋ง์ดํธ/์ธ๋ง์ดํธ ์ํค๋ ์ฝ๋์ด๋ค.
๋ถ์ ์ฐ์ฐ์, ์ผํญ ์ฐ์ฐ์, ๋ ผ๋ฆฌํฉ(&&)์ด ๋ฑ์ฅํ๋๋ฐ ์ฃผ์์ ์ฐธ๊ณ ํ๋ฉด ๋๋ค.
๊ทธ๋ผ ์ด์ ๋ฒํผ์ ๋๋ ์ ๋, isOpen์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด์ <PopupComponent/>๊ฐ ๋ํ๋๋๋ฐ
PopupComponent๋ ์๋์ ๊ฐ๋ค.
๐ PopupComponent.tsx
import React, { useEffect } from 'react'
export function PopupComponent(): JSX.Element {
useEffect(() => {
console.log('๋ฉ๋กฑ')
return () => {
console.log('Bye')
}
})
return <div>๐</div>
}
์์ฑ ํ, ์ง์ ํ๋ App.tsx์ ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ฅผ ํธ์ถํ๋ฉด ๋๋ค.
๐ App.tsx
import { EffectComponent } from './components/EffectComponent'
function App(): JSX.Element {
return (
<>
<EffectComponent />
</>
)
}
export default App
์ด์ ๋ฆฌ์กํธ ์๋ฒ๋ฅผ ์คํํ๊ณ Ctrl + F12 ๋ฅผ ๋๋ฌ ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ด์ด Console ํญ์ผ๋ก ์ด๋ํ๋ค.

์ด์ "์ด๊ธฐ"๋ฒํผ์ ๋๋ฌ ํ์ธํด๋ณด์.

์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ ๋๋ฉด์ useEffect()๊ฐ ์คํ๋๋ค.
โ๋ง์ดํธ๋ง ์์ผฐ๋๋ฐ ์ "Bye"๊ฐ ์ฐํ์ง?
๋ฆฌ์กํธ๋ ๊ฐ๋ฐ ์ <React.StrictMode>๋ฅผ ์ง์ํ๋๋ฐ, ์ด๋ ์ค๋ฅ ๊ฒ์ฌ๋ฅผ ํ๊ธฐ ์ํด 2๋ฒ์ ๋ ๋๋ง์ด ๋ฐ์ํ๋ค.
๋ฐ๋ผ์ ํ ๋ฒ ๋ ๋๋ง ๋๊ณ , ์ธ๋ง์ดํธ ํ ๋ค์ ๋ ๋๋ง์ ํด์
"๋ฉ๋กฑ" - "Bye" - "๋ฉ๋กฑ"์ด ๋ํ๋๋ค.
๊ฑฐ์ฌ๋ฆฐ๋คํ๋ฉด์ main.tsx ํ์ผ์ ๊ฐ์ <React.StrictMode>๋ฅผ ์ง์์ฃผ๋ฉด ๋๋ค.
๐ main.tsx
import './assets/main.css'
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />)

useEffect ๊ฒ์๊ธ์ด ๊ทธ๋๋ ์กฐํ์๊ฐ ๋์์ ์ถ๊ฐ์ ์ผ๋ก ํ๋ ๋ ์ ๊ฒ ์ต๋๋ค.
window๋ ํ์ฌ ์ฌ๋ฌ๋ถ์ด ๋ณด๊ณ ์๋ ์น ํ๋ฉด์ ๊ฐ์ธ๋ ์์ ๊ฐ์ธต์ ์ ์ญ๊ด๋ฆฌ ์ฐฝ์ ๋๋ค.
์ด ์๋์ฐ์ ์ด๋ฒคํธ๋ฅผ ๋ฌ๊ณ , ํ๋ฉด ์ด๋๋ ํด๋ฆญํ ๋๋ง๋ค state๋ฅผ ์ถ๋ ฅํ๊ณ ์ถ์ ๋,
๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ค๊ณ ์๋ก ๋ค๋,
function WindowEventRegister() {
const [value, setValue] = useState<numner>(1);
const handleClickLog = (): void => {
console.log(value);
};
const handleClickIncrease = (): void => {
setValue(value + 1);
};
useEffect(() => {
window.addEventListener("mousedown", handleClickLog);
return () => {
window.removeEventListener("mousedown", handleClickLog);
};
//์๋ dependencies์ value์ ์ฌ๋ถ๋ฅผ ํ
์คํธํด๋ณด๊ธฐ.
}, [value]);
return (
<div>
<button onClick={handleClickLog}>Log</button>
<button onClick={handleClickIncrease}>Increase</button>
</div>
)
}
value๋ฅผ ์ ๊ฑฐํ๋ฉด ๋ณ๊ฒฝ๋ state๊ฐ ์๋์ฐ์ ์ ์ฅ๋ ๊ฒ์ด ์๋๋ผ ๊ณ์ 1์ด ์ถ๋ ฅ๋๊ณ ,
value์ ๋ฐ๋ผ window์ ๋ค์ state๋ฅผ ๋ฑ๋ก ๋ฐ ์๋ ค์ฃผ์ด ์๋์ฐ๊ฐ ๋ณ๊ฒฝ๋ value๊ฐ์ ์ถ๋ ฅํ ์ ์๋๋ก ์ฌ์ฉํ๋ ์ฉ๋๋ก๋ ์ฐ์ ๋๋ค.
'Library > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ React ] useMemo์ ๋ํด ์์๋ณด์. (0) | 2024.04.04 |
---|---|
[ React ] useRef์ ๋ํด ์์๋ณด์. (0) | 2024.04.04 |
[ React ] useState()๋ฅผ ํ์ฉํด๋ณด์. (feat. TypeScript) (0) | 2024.03.11 |
[ React ] CRA - ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ณด์. (0) | 2024.03.06 |
[ React ] ๋ฆฌ์กํธ์ ๋ํด ์์๋ณด์. (0) | 2024.03.06 |

๐ useEffect
useEffect()๋ ํ์ด์ง์ ๋ง์ดํธ, ์ธ๋ง์ดํธ, ์ ๋ฐ์ดํธ ์ ์์ ์ ์ค์ ํ๋ค.
์ฉ์ด | ์ค๋ช |
Mount | ์ปดํฌ๋ํธ๊ฐ ํ์ด์ง์ ๋ํ๋จ |
unMount | ์ปดํฌ๋ํธ๊ฐ ํ์ด์ง์์ ์ฌ๋ผ์ง |
์ ๋ฐ์ดํธ๋ useEffect() ํน์ ๊ฐ์ ์์กดํ์ฌ ํด๋น ๊ฐ์ด ๋ณ๊ฒฝ, ์คํ๋๋ฉด ํด๋น useEffect()๋ฅผ ์ฌ์คํํ๋ค.
useEffect()์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
useEffect(()=> {
// ๋ง์ดํธ ์๋ฃ ํ ์คํํ ์ฝ๋
return () => {
// ์ธ๋ง์ดํธ ์๋ฃ ํ ์คํํ ์ฝ๋
}
}, [dependencies])
dependencies์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ์ธ๋ง์ดํธ๊ฐ ์ผ์ด๋๋ฉด์ return()์ ํตํด ๊ธฐ์กด ์์ ์ ํด์ ํ๊ณ ๋ค์ ๋ง์ดํธ ์ํจ๋ค.
๐ป Code
๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ค.
๐ EffectComponent.tsx
import React, { useEffect, useState } from 'react'
import { PopupComponent } from './PopupComponent'
export function EffectComponent(): JSX.Element {
const [isOpen, setIsOpen] = useState<boolean>(false)
// !: ๋ถ์ ์ฐ์ฐ์ boolํ์
์ ๊ฐ์ ๋ฐ๋๊ฐ์ผ๋ก ๋ณํํฉ๋๋ค.
// true -> false
// false -> true
const handlerBoolean = () => setIsOpen(!isOpen)
return (
<div style={{ textAlign: 'center' }}>
/* ์ผํญ ์ฐ์ฐ์
//์กฐ๊ฑด ? ์กฐ๊ฑด์ด true์ผ ๋ ๋ฐํ๊ฐ : ์กฐ๊ฑด์ด false์ผ ๋ ๋ฐํ๊ฐ
/*
<button onClick={handlerBoolean}>{isOpen ? '๋ซ๊ธฐ' : '์ด๊ธฐ'}</button>
/* ๋
ผ๋ฆฌ๊ณฑ(&&)
// ์ผ์ชฝ๋ถํฐ ๊ฐ์ ๊ฒ์ฌํ์ฌ true๊ฐ์ ๊ฐ์ง๋ฉด ๋ง์ง๋ง ๊ฐ์ ๋ฐํ
*/
{isOpen && <PopupComponent />}
</div>
)
}
isOpen์ ์ํ์ ๋ฐ๋ผ์ ์ปดํฌ๋ํธ(<PopupComponent/>)๋ฅผ ํ์ด์ง์ ๋ง์ดํธ/์ธ๋ง์ดํธ ์ํค๋ ์ฝ๋์ด๋ค.
๋ถ์ ์ฐ์ฐ์, ์ผํญ ์ฐ์ฐ์, ๋ ผ๋ฆฌํฉ(&&)์ด ๋ฑ์ฅํ๋๋ฐ ์ฃผ์์ ์ฐธ๊ณ ํ๋ฉด ๋๋ค.
๊ทธ๋ผ ์ด์ ๋ฒํผ์ ๋๋ ์ ๋, isOpen์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด์ <PopupComponent/>๊ฐ ๋ํ๋๋๋ฐ
PopupComponent๋ ์๋์ ๊ฐ๋ค.
๐ PopupComponent.tsx
import React, { useEffect } from 'react'
export function PopupComponent(): JSX.Element {
useEffect(() => {
console.log('๋ฉ๋กฑ')
return () => {
console.log('Bye')
}
})
return <div>๐</div>
}
์์ฑ ํ, ์ง์ ํ๋ App.tsx์ ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ฅผ ํธ์ถํ๋ฉด ๋๋ค.
๐ App.tsx
import { EffectComponent } from './components/EffectComponent'
function App(): JSX.Element {
return (
<>
<EffectComponent />
</>
)
}
export default App
์ด์ ๋ฆฌ์กํธ ์๋ฒ๋ฅผ ์คํํ๊ณ Ctrl + F12 ๋ฅผ ๋๋ฌ ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ด์ด Console ํญ์ผ๋ก ์ด๋ํ๋ค.

์ด์ "์ด๊ธฐ"๋ฒํผ์ ๋๋ฌ ํ์ธํด๋ณด์.

์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ ๋๋ฉด์ useEffect()๊ฐ ์คํ๋๋ค.
โ๋ง์ดํธ๋ง ์์ผฐ๋๋ฐ ์ "Bye"๊ฐ ์ฐํ์ง?
๋ฆฌ์กํธ๋ ๊ฐ๋ฐ ์ <React.StrictMode>๋ฅผ ์ง์ํ๋๋ฐ, ์ด๋ ์ค๋ฅ ๊ฒ์ฌ๋ฅผ ํ๊ธฐ ์ํด 2๋ฒ์ ๋ ๋๋ง์ด ๋ฐ์ํ๋ค.
๋ฐ๋ผ์ ํ ๋ฒ ๋ ๋๋ง ๋๊ณ , ์ธ๋ง์ดํธ ํ ๋ค์ ๋ ๋๋ง์ ํด์
"๋ฉ๋กฑ" - "Bye" - "๋ฉ๋กฑ"์ด ๋ํ๋๋ค.
๊ฑฐ์ฌ๋ฆฐ๋คํ๋ฉด์ main.tsx ํ์ผ์ ๊ฐ์ <React.StrictMode>๋ฅผ ์ง์์ฃผ๋ฉด ๋๋ค.
๐ main.tsx
import './assets/main.css'
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />)

useEffect ๊ฒ์๊ธ์ด ๊ทธ๋๋ ์กฐํ์๊ฐ ๋์์ ์ถ๊ฐ์ ์ผ๋ก ํ๋ ๋ ์ ๊ฒ ์ต๋๋ค.
window๋ ํ์ฌ ์ฌ๋ฌ๋ถ์ด ๋ณด๊ณ ์๋ ์น ํ๋ฉด์ ๊ฐ์ธ๋ ์์ ๊ฐ์ธต์ ์ ์ญ๊ด๋ฆฌ ์ฐฝ์ ๋๋ค.
์ด ์๋์ฐ์ ์ด๋ฒคํธ๋ฅผ ๋ฌ๊ณ , ํ๋ฉด ์ด๋๋ ํด๋ฆญํ ๋๋ง๋ค state๋ฅผ ์ถ๋ ฅํ๊ณ ์ถ์ ๋,
๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ค๊ณ ์๋ก ๋ค๋,
function WindowEventRegister() {
const [value, setValue] = useState<numner>(1);
const handleClickLog = (): void => {
console.log(value);
};
const handleClickIncrease = (): void => {
setValue(value + 1);
};
useEffect(() => {
window.addEventListener("mousedown", handleClickLog);
return () => {
window.removeEventListener("mousedown", handleClickLog);
};
//์๋ dependencies์ value์ ์ฌ๋ถ๋ฅผ ํ
์คํธํด๋ณด๊ธฐ.
}, [value]);
return (
<div>
<button onClick={handleClickLog}>Log</button>
<button onClick={handleClickIncrease}>Increase</button>
</div>
)
}
value๋ฅผ ์ ๊ฑฐํ๋ฉด ๋ณ๊ฒฝ๋ state๊ฐ ์๋์ฐ์ ์ ์ฅ๋ ๊ฒ์ด ์๋๋ผ ๊ณ์ 1์ด ์ถ๋ ฅ๋๊ณ ,
value์ ๋ฐ๋ผ window์ ๋ค์ state๋ฅผ ๋ฑ๋ก ๋ฐ ์๋ ค์ฃผ์ด ์๋์ฐ๊ฐ ๋ณ๊ฒฝ๋ value๊ฐ์ ์ถ๋ ฅํ ์ ์๋๋ก ์ฌ์ฉํ๋ ์ฉ๋๋ก๋ ์ฐ์ ๋๋ค.
'Library > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ React ] useMemo์ ๋ํด ์์๋ณด์. (0) | 2024.04.04 |
---|---|
[ React ] useRef์ ๋ํด ์์๋ณด์. (0) | 2024.04.04 |
[ React ] useState()๋ฅผ ํ์ฉํด๋ณด์. (feat. TypeScript) (0) | 2024.03.11 |
[ React ] CRA - ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ณด์. (0) | 2024.03.06 |
[ React ] ๋ฆฌ์กํธ์ ๋ํด ์์๋ณด์. (0) | 2024.03.06 |