<StrictMode>
<StrictMode>
๋ ๊ฐ๋ฐ ์ค์ ์ปดํฌ๋ํธ์์ ์ผ๋ฐ์ ์ธ ๋ฒ๊ทธ๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์๋๋ก ํฉ๋๋ค.
<StrictMode>
<App />
</StrictMode>
๋ ํผ๋ฐ์ค
<StrictMode>
์ปดํฌ๋ํธ ํธ๋ฆฌ ๋ด๋ถ์์ ์ถ๊ฐ์ ์ธ ๊ฐ๋ฐ ๋์ ๋ฐ ๊ฒฝ๊ณ ๋ฅผ ํ์ฑํํ๊ธฐ ์ํด StrictMode
๋ฅผ ์ฌ์ฉํ์ธ์.
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);
์๋์์ ๋ ๋ง์ ์์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
Strict Mode๋ ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋ฐ ์ ์ฉ ๋์์ ํ์ฑํํฉ๋๋ค.
- ์์ํ์ง ์์ ๋ ๋๋ง์ผ๋ก ์ธํด ๋ฐ์ํ๋ ๋ฒ๊ทธ๋ฅผ ์ฐพ๊ธฐ ์ํด ์ปดํฌ๋ํธ๊ฐ ์ถ๊ฐ๋ก ๋ค์ ๋ ๋๋ง๋ฉ๋๋ค.
- Effect ํด๋ฆฐ์ ์ด ๋๋ฝ๋์ด ๋ฐ์ํ๋ ๋ฒ๊ทธ๋ฅผ ์ฐพ๊ธฐ ์ํด ์ปดํฌ๋ํธ๊ฐ ์ถ๊ฐ๋ก Effect๋ฅผ ๋ค์ ์คํํฉ๋๋ค.
- ๋ ์ด์ ์ฌ์ฉ๋์ง ์๋ API์ ์ฌ์ฉ ์ฌ๋ถ๋ฅผ ํ์ธํ๊ธฐ ์ํด ์ปดํฌ๋ํธ๋ฅผ ๊ฒ์ฌํฉ๋๋ค.
Props
StrictMode
๋ props๋ฅผ ํ์ฉํ์ง ์์ต๋๋ค.
์ฃผ์ ์ฌํญ
<StrictMode>
๋ก ๋ํ๋ ํธ๋ฆฌ ๋ด์์ Strict Mode๋ฅผ ํด์ ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด<StrictMode>
๋ด๋ถ์ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๊ฒ์ฌ๋์์์ ํ์ ํ ์ ์์ต๋๋ค. ์ ํ์ ๊ฐ๋ฐํ๋ ๋ ํ์ด ๊ฒ์ฌ๊ฐ ๊ฐ์น ์๋์ง์ ๋ํด ์๊ฒฌ์ด ๊ฐ๋ฆฌ๋ ๊ฒฝ์ฐ, ํฉ์์ ๋๋ฌํ๊ฑฐ๋<StrictMode>
๋ฅผ ํธ๋ฆฌ์์ ํ๋จ์ผ๋ก ์ฎ๊ฒจ์ผ ํฉ๋๋ค.
์ฌ์ฉ ๋ฐฉ๋ฒ
์ ์ฒด ์ฑ์ ๋ํด Strict Mode ํ์ฑํ
Strict Mode๋ <StrictMode>
์ปดํฌ๋ํธ ๋ด๋ถ์ ๋ชจ๋ ์ปดํฌ๋ํธ ํธ๋ฆฌ์ ๋ํด ์ถ๊ฐ์ ์ธ ๊ฐ๋ฐ ์ ์ฉ ๊ฒ์ฌ๋ฅผ ํ์ฑํํฉ๋๋ค. ์ด๋ฌํ ๊ฒ์ฌ๋ ๊ฐ๋ฐ ํ๋ก์ธ์ค ์ด๊ธฐ์ ์ปดํฌ๋ํธ์์ ์ผ๋ฐ์ ์ธ ๋ฒ๊ทธ๋ฅผ ์ฐพ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
์ ์ฒด ์ฑ์ ๋ํ Strict Mode๋ฅผ ํ์ฑํํ๋ ค๋ฉด ๋ ๋๋งํ ๋ ๋ฃจํธ ์ปดํฌ๋ํธ๋ฅผ <StrictMode>
๋ก ๋ํํ์ธ์.
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);
์ ์ฒด ์ฑ์ (ํนํ ์๋ก ์์ฑ๋ ์ฑ์ ๊ฒฝ์ฐ) Strict Mode๋ก ๋ํํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค. createRoot
๋ฅผ ํธ์ถํ๋ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, Strict Mode๋ฅผ ํ์ฑํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ฌธ์๋ฅผ ํ์ธํ์ธ์.
Strict Mode ๊ฒ์ฌ๋ ๊ฐ๋ฐ ํ๊ฒฝ์์๋ง ์คํ๋์ง๋ง, ์ด๋ฏธ ์ฝ๋์ ์กด์ฌํ์ง๋ง ํ๋ก๋์ ์์ ์ ๋๋ก ์ฌํํ๊ธฐ ์ด๋ ค์ธ ์ ์๋ ๋ฒ๊ทธ๋ฅผ ์ฐพ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. Strict Mode๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ์ฉ์๊ฐ ๋ณด๊ณ ํ๊ธฐ ์ ์ ๋ฒ๊ทธ๋ฅผ ์์ ํ ์ ์์ต๋๋ค.
์ฑ์ ์ผ๋ถ๋ถ์์ Strict Mode ํ์ฑํ
์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ค ๋ถ๋ถ์์๋ผ๋ Strict Mode๋ฅผ ํ์ฑํํ ์ ์์ต๋๋ค.
import { StrictMode } from 'react';
function App() {
return (
<>
<Header />
<StrictMode>
<main>
<Sidebar />
<Content />
</main>
</StrictMode>
<Footer />
</>
);
}
์ด ์์์์ Header
์ Footer
์ปดํฌ๋ํธ์์๋ Strict Mode ๊ฒ์ฌ๊ฐ ์คํ๋์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ Sidebar
์ Content
, ๊ทธ๋ฆฌ๊ณ ๊ทธ ์์ ์ปดํฌ๋ํธ๋ ๊น์ด์ ์๊ด์์ด ๊ฒ์ฌ๊ฐ ์คํ๋ฉ๋๋ค.
๊ฐ๋ฐ ์ค ์ด์ค ๋ ๋๋ง์ผ๋ก ๋ฐ๊ฒฌํ ๋ฒ๊ทธ ์์
React๋ ์์ฑํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ์์ ํจ์๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค. ์ด๊ฒ์ React ์ปดํฌ๋ํธ๋ ํญ์ ๋์ผํ ์ ๋ ฅ(props, state, context)์ ๋ํด ๋์ผํ JSX๋ฅผ ๋ฐํํด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์ด ๊ท์น์ ์๋ฐํ๋ ์ปดํฌ๋ํธ๋ ์๊ธฐ์น ์๊ฒ ๋์ํ๋ฉฐ ๋ฒ๊ทธ๋ฅผ ์ผ์ผํต๋๋ค. Strict Mode๋ ์ค์๋ก ์์ฑ๋ ์์ํ์ง ์์ ์ฝ๋๋ฅผ ์ฐพ์๋ด๊ธฐ ์ํด ๋ช ๊ฐ์ง ํจ์(์์ ํจ์์ฌ์ผ ํ๋ ๊ฒ๋ง)๋ฅผ ๊ฐ๋ฐ ํ๊ฒฝ์์ ๋ ๋ฒ ํธ์ถํฉ๋๋ค. ์ด์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค.
- ์ปดํฌ๋ํธ ํจ์ ๋ณธ๋ฌธ (์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ ์ฝ๋๋ฅผ ํฌํจํ์ง ์๋๋ก ์ต์์ ๋ก์ง์์๋ง)
useState
,set
ํจ์,useMemo
, ๋๋useReducer
์ ์ ๋ฌํ ํจ์constructor
,render
,shouldComponentUpdate
์ ๊ฐ์ ์ผ๋ถ ํด๋์ค ์ปดํฌ๋ํธ ๋ฉ์๋ (์ ์ฒด ๋ชฉ๋ก ๋ณด๊ธฐ)
ํจ์๊ฐ ์์ํ ๊ฒฝ์ฐ ๋ ๋ฒ ์คํํ์ฌ๋ ๋์์ด ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค. ์์ ํจ์๋ ํญ์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ํจ์๊ฐ ์์ํ์ง ์๋ค๋ฉด (์: ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์) ๋ ๋ฒ ์คํํ๋ฉด ๋ณดํต ์์์ฑ ์ ์์ต๋๋ค. (์ด๊ฒ์ด ์์ํ์ง ์์ ์ด์ ์ ๋๋ค!) ์ด๋ ๋ฒ๊ทธ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ๊ณ ์์ ํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
๋ค์์ Strict Mode์ ์ด์ค ๋ ๋๋ง์ด ์ด๋ป๊ฒ ๋ฒ๊ทธ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ๋ ๋ฐ ๋์์ด ๋๋์ง ๋ณด์ฌ์ฃผ๋ ์์์ ๋๋ค.
StoryTray
์ปดํฌ๋ํธ๋ stories
๋ฐฐ์ด์ ๋ฐ์ ๋ง์ง๋ง์ โ์ด์ผ๊ธฐ ๋ง๋ค๊ธฐโ ํญ๋ชฉ์ ์ถ๊ฐํฉ๋๋ค.
export default function StoryTray({ stories }) { const items = stories; items.push({ id: 'create', label: '์ด์ผ๊ธฐ ๋ง๋ค๊ธฐ' }); return ( <ul> {items.map(story => ( <li key={story.id}> {story.label} </li> ))} </ul> ); }
์ ์ฝ๋์๋ ์ค์๊ฐ ์์ต๋๋ค. ํ์ง๋ง ์ด๊ธฐ ์ถ๋ ฅ์ด ์ฌ๋ฐ๋ฅด๊ฒ ๋ํ๋๊ธฐ ๋๋ฌธ์ ๋์น๊ธฐ ์ฝ์ต๋๋ค.
์ด ์ค์๋ StoryTray
์ปดํฌ๋ํธ๊ฐ ์ฌ๋ฌ ๋ฒ ๋ค์ ๋ ๋๋งํ๋ฉด ๋ ๋์ ๋๊ฒ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด StoryTray
์ ๋ง์ฐ์ค๋ฅผ ์ฌ๋ ค๋์ ๋๋ง๋ค ๋ค๋ฅธ ๋ฐฐ๊ฒฝ์์ผ๋ก ๋ค์ ๋ ๋๋งํ๋๋ก ํด ๋ณด๊ฒ ์ต๋๋ค.
import { useState } from 'react'; export default function StoryTray({ stories }) { const [isHover, setIsHover] = useState(false); const items = stories; items.push({ id: 'create', label: '์ด์ผ๊ธฐ ๋ง๋ค๊ธฐ' }); return ( <ul onPointerEnter={() => setIsHover(true)} onPointerLeave={() => setIsHover(false)} style={{ backgroundColor: isHover ? '#ddd' : '#fff' }} > {items.map(story => ( <li key={story.id}> {story.label} </li> ))} </ul> ); }
StoryTray
์ปดํฌ๋ํธ ์๋ก ๋ง์ฐ์ค๋ฅผ ๊ฐ์ ธ๊ฐ ๋๋ง๋ค โ์ด์ผ๊ธฐ ๋ง๋ค๊ธฐโ๊ฐ ๋ชฉ๋ก์ ๋ค์ ์ถ๊ฐ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ด ์ฝ๋์ ์๋๋ ๋ง์ง๋ง์ ํ ๋ฒ ์ถ๊ฐํ๋ ๊ฒ์ด์์ต๋๋ค. ํ์ง๋ง StoryTray
๋ ์ํ์ stories
๋ฐฐ์ด์ ์ง์ ์์ ํฉ๋๋ค. StoryTray
๋ ๋ ๋๋งํ ๋๋ง๋ค ๊ฐ์ ๋ฐฐ์ด์ ๋์ โ์ด์ผ๊ธฐ ๋ง๋ค๊ธฐโ๋ฅผ ๋ค์ ์ถ๊ฐํฉ๋๋ค. ์ฆ, StoryTray
๋ ์์ ํจ์๊ฐ ์๋๋ฏ๋ก ์ฌ๋ฌ ๋ฒ ์คํํ๋ฉด ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ์์ฑ๋ฉ๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฐฐ์ด์ ์ฌ๋ณธ์ ๋ง๋ ๋ค์ ์๋ณธ์ด ์๋ ์ฌ๋ณธ์ ์์ ํ ์ ์์ต๋๋ค.
export default function StoryTray({ stories }) {
const items = stories.slice(); // ๋ฐฐ์ด ๋ณต์
// โ
Good: ์๋ก์ด ๋ฐฐ์ด์ ์ถ๊ฐ
items.push({ id: 'create', label: '์ด์ผ๊ธฐ ๋ง๋ค๊ธฐ' });
์ด๋ ๊ฒ ํ๋ฉด StoryTray
ํจ์๋ฅผ ์์ํ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. ํจ์๊ฐ ํธ์ถ๋ ๋๋ง๋ค ๋ฐฐ์ด์ ์ฌ๋ณธ๋ง ์์ ํ๊ณ ์ธ๋ถ ๊ฐ์ฒด๋ ๋ณ์์ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ฒ๊ทธ๊ฐ ํด๊ฒฐ๋์ง๋ง ์ปดํฌ๋ํธ์ ๋์์ ๋ฌธ์ ๊ฐ ์๋ค๋ ๊ฒ์ด ๋ช
ํํด์ง๊ธฐ ์ ์ ์ปดํฌ๋ํธ๋ฅผ ๋ ์์ฃผ ๋ค์ ๋ ๋๋งํด์ผ ํ์ต๋๋ค.
์๋ ์์์์๋ ๋ฒ๊ทธ๊ฐ ๋ช
ํํ์ง ์์์ต๋๋ค. ์ด์ ์๋ (๋ฒ๊ทธ๊ฐ ์๋) ์ฝ๋๋ฅผ <StrictMode>
๋ก ๋ํํด ๋ณด๊ฒ ์ต๋๋ค.
export default function StoryTray({ stories }) { const items = stories; items.push({ id: 'create', label: '์ด์ผ๊ธฐ ๋ง๋ค๊ธฐ' }); return ( <ul> {items.map(story => ( <li key={story.id}> {story.label} </li> ))} </ul> ); }
Strict Mode์์๋ ํญ์ ๋ ๋๋ง ํจ์๋ฅผ ๋ ๋ฒ ํธ์ถํ๋ฏ๋ก ์ค์๋ฅผ ๋ฐ๋ก ํ์ธํ ์ ์์ต๋๋ค(โ์ด์ผ๊ธฐ ๋ง๋ค๊ธฐโ๊ฐ ๋ ๋ฒ ๋ํ๋จ). ๋ฐ๋ผ์ ํ๋ก์ธ์ค ์ด๊ธฐ์ ์ด๋ฌํ ์ค์๋ฅผ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค. ์ปดํฌ๋ํธ๊ฐ Strict Mode์์ ๋ ๋๋ง๋๋๋ก ์์ ํ๋ฉด ์ด์ ์ ํธ๋ฒ ๊ธฐ๋ฅ๊ณผ ๊ฐ์ด ํฅํ ๋ฐ์ํ ์ ์๋ ๋ง์ ํ๋ก๋์ ๋ฒ๊ทธ๋ ์์ ํ ์ ์์ต๋๋ค.
import { useState } from 'react'; export default function StoryTray({ stories }) { const [isHover, setIsHover] = useState(false); const items = stories.slice(); // ๋ฐฐ์ด ๋ณต์ items.push({ id: 'create', label: '์ด์ผ๊ธฐ ๋ง๋ค๊ธฐ' }); return ( <ul onPointerEnter={() => setIsHover(true)} onPointerLeave={() => setIsHover(false)} style={{ backgroundColor: isHover ? '#ddd' : '#fff' }} > {items.map(story => ( <li key={story.id}> {story.label} </li> ))} </ul> ); }
Strict Mode๊ฐ ์์ผ๋ฉด ๋ฆฌ๋ ๋๋ง์ ๋ ์ถ๊ฐํ๊ธฐ ์ ๊น์ง๋ ๋ฒ๊ทธ๋ฅผ ๋์น๊ธฐ ์ฌ์ ์ต๋๋ค. Strict Mode๋ฅผ ์ฌ์ฉํ๋ฉด ๋์ผํ ๋ฒ๊ทธ๊ฐ ์ฆ์ ๋ํ๋ฉ๋๋ค. Strict Mode๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฒ๊ทธ๋ฅผ ํ๊ณผ ์ฌ์ฉ์์๊ฒ ํธ์ํ๊ธฐ ์ ์ ๋ฐ๊ฒฌํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
์ปดํฌ๋ํธ๋ฅผ ์์ํ๊ฒ ์ ์งํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์ธํ ์์๋ณด์ธ์.
๊ฐ๋ฐ ํ๊ฒฝ์์ Effect๋ฅผ ๋ค์ ์คํํ์ฌ ๋ฐ๊ฒฌ๋ ๋ฒ๊ทธ ์์
Strict Mode๋ Effects์ ๋ฒ๊ทธ๋ฅผ ์ฐพ๋ ๋ฐ๋ ๋์์ด ๋ ์ ์์ต๋๋ค.
๋ชจ๋ Effect์๋ ๋ช ๊ฐ์ง ์ ์ ์ฝ๋๊ฐ ์๊ณ ์ด์ฉ๋ฉด ํด๋ฆฐ์ ์ฝ๋๊ฐ ์์ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก React๋ ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ(ํ๋ฉด์ ์ถ๊ฐ)๋ ๋ ์ ์ ์ ํธ์ถํ๊ณ ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ ํด์ (ํ๋ฉด์์ ์ ๊ฑฐ)๋ ๋ ํด๋ฆฐ์ ์ ํธ์ถํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ React๋ ๋ง์ง๋ง ๋ ๋๋ง ์ดํ๋ก๋ถํฐ ์์กด์ฑ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ํด๋ฆฐ์ ๊ณผ ์ ์ ์ ๋ค์ ํธ์ถํฉ๋๋ค.
Strict Mode๊ฐ ์ผ์ ธ ์์ผ๋ฉด React๋ ๋ชจ๋ Effect์ ๋ํด ๊ฐ๋ฐ ํ๊ฒฝ์์ ํ ๋ฒ ๋ ์ ์ +ํด๋ฆฐ์ ์ฌ์ดํด์ ์คํํฉ๋๋ค. ์์ธ๋ก ๋๊ปด์ง ์๋ ์์ง๋ง ์๋์ผ๋ก ํ์ ํ๊ธฐ ์ด๋ ค์ด ๋ฏธ๋ฌํ ๋ฒ๊ทธ๋ฅผ ๋๋ฌ๋ด๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
๋ค์์ Strict Mode์์ Effects๋ฅผ ๋ค์ ์คํํ๋ ๊ฒ์ด ๋ฒ๊ทธ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ๋ ๋ฐ ์ด๋ป๊ฒ ๋์์ด ๋๋์ง ๋ณด์ฌ์ฃผ๋ ์์์ ๋๋ค.
์ปดํฌ๋ํธ๋ฅผ ์ฑํ ์ ์ฐ๊ฒฐํ๋ ์ด ์์๋ฅผ ์ดํด๋ด ์๋ค.
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; const roomId = '์ผ๋ฐ'; export default function ChatRoom() { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); }, []); return <h1>{roomId} ๋ฐฉ์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค!</h1>; }
์ด ์ฝ๋์๋ ๋ฌธ์ ๊ฐ ์์ง๋ง ์ฆ์ ํ์ ํ๊ธฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
๋ฌธ์ ๋ฅผ ๋ ๋ช
ํํ๊ฒ ๋๋ฌ๋ด๊ธฐ ์ํด ๊ธฐ๋ฅ์ ๊ตฌํํด ๋ณด๊ฒ ์ต๋๋ค. ์๋ ์์์์๋ roomId
๊ฐ ํ๋์ฝ๋ฉ๋์ด ์์ง ์์ต๋๋ค. ๋์ ์ฌ์ฉ์๊ฐ ์ฐ๊ฒฐํ๋ ค๋ roomId
๋ฅผ ๋๋กญ๋ค์ด์์ ์ ํํ ์ ์์ต๋๋ค. โ๋ํ ์ด๊ธฐโ์ ํด๋ฆญํ ๋ค์ ๋ค๋ฅธ ๋ํ๋ฐฉ์ ํ๋์ฉ ์ ํํฉ๋๋ค. ์ฝ์์์ ํ์ฑํ๋ ์ฐ๊ฒฐ ์๋ฅผ ์ถ์ ํฉ๋๋ค.
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); }, [roomId]); return <h1>{roomId} ๋ฐฉ์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค!</h1>; } export default function App() { const [roomId, setRoomId] = useState('์ผ๋ฐ'); const [show, setShow] = useState(false); return ( <> <label> ๋ํ๋ฐฉ ์ ํํ๊ธฐ:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="์ผ๋ฐ">์ผ๋ฐ</option> <option value="์ฌํ">์ฌํ</option> <option value="์์ ">์์ </option> </select> </label> <button onClick={() => setShow(!show)}> {show ? '๋ํ ๋ซ๊ธฐ' : '๋ํ ์ด๊ธฐ'} </button> {show && <hr />} {show && <ChatRoom roomId={roomId} />} </> ); }
์ด๋ฆฐ ์ฐ๊ฒฐ ์๊ฐ ํญ์ ๊ณ์ ์ฆ๊ฐํ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ค์ ์ฑ์์๋ ์ฑ๋ฅ ๋ฐ ๋คํธ์ํฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ฌธ์ ๋ Effect์ ํด๋ฆฐ์ ํจ์๊ฐ ๋๋ฝ๋์๋ค๋ ๊ฒ์ ๋๋ค.
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);
์ด์ Effect๊ฐ ์์ฒด์ ์ผ๋ก โํด๋ฆฐ์ โํ๊ณ ์ค๋๋ ์ฐ๊ฒฐ์ ํ๊ดดํ๋ฏ๋ก ๋์๊ฐ ํด๊ฒฐ๋์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ ๋ง์ ๊ธฐ๋ฅ(์ ํ ์์)์ ์ถ๊ฐํ๊ธฐ ์ ๊น์ง๋ ๋ฌธ์ ๊ฐ ๋๋ฌ๋์ง ์์์์ ์ ์ ์์ต๋๋ค.
์๋ ์์์์๋ ๋ฒ๊ทธ๊ฐ ๋ช
ํํ์ง ์์์ต๋๋ค. ์ด์ ์๋ (๋ฒ๊ทธ๊ฐ ์๋) ์ฝ๋๋ฅผ <StrictMode>
๋ก ๋ํํด ๋ณด๊ฒ ์ต๋๋ค.
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; const roomId = '์ผ๋ฐ'; export default function ChatRoom() { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); }, []); return <h1>{roomId} ๋ฐฉ์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค!</h1>; }
Strict Mode๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๊ฐ ์์์ ์ฆ์ ์ ์ ์์ต๋๋ค(ํ์ฑํ๋ ์ฐ๊ฒฐ ์๊ฐ 2๊ฐ๋ก ์ฆ๊ฐํจ). Strict Mode๋ ๋ชจ๋ Effect์ ๋ํด ์ถ๊ฐ ์ ์ +ํด๋ฆฐ์ ์ฌ์ดํด์ ์คํํฉ๋๋ค. ์ด Effect์๋ ํด๋ฆฐ์ ๋ก์ง์ด ์์ผ๋ฏ๋ก ์ถ๊ฐ ์ฐ๊ฒฐ์ ์์ฑํ์ง๋ง ํ๊ดดํ์ง๋ ์์ต๋๋ค. ์ด๊ฒ์ ํด๋ฆฐ์ ํจ์๊ฐ ๋๋ฝ๋์๋ค๋ ํํธ์ ๋๋ค.
Strict Mode๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ์ค์๋ฅผ ํ๋ก์ธ์ค ์ด๊ธฐ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค. Strict Mode์์ ํด๋ฆฐ์ ํจ์๋ฅผ ์ถ๊ฐํ์ฌ Effect๋ฅผ ์์ ํ๋ฉด ์ด์ ์ ์ ํ ์์์ ๊ฐ์ด ํฅํ ํ๋ก๋์ ์์ ๋ฐ์ํ ์ ์๋ ๋ง์ ๋ฒ๊ทธ ๋ํ ์์ ํฉ๋๋ค.
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => connection.disconnect(); }, [roomId]); return <h1>{roomId} ๋ฐฉ์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค!</h1>; } export default function App() { const [roomId, setRoomId] = useState('์ผ๋ฐ'); const [show, setShow] = useState(false); return ( <> <label> ๋ํ๋ฐฉ ์ ํํ๊ธฐ:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="์ผ๋ฐ">์ผ๋ฐ</option> <option value="์ฌํ">์ฌํ</option> <option value="์์ ">์์ </option> </select> </label> <button onClick={() => setShow(!show)}> {show ? '๋ํ ๋ซ๊ธฐ' : '๋ํ ์ด๊ธฐ'} </button> {show && <hr />} {show && <ChatRoom roomId={roomId} />} </> ); }
์ฝ์์ ํ์ฑํ๋ ์ฐ๊ฒฐ ์๊ฐ ๋ ์ด์ ์ฆ๊ฐํ์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
Strict Mode๊ฐ ์์ผ๋ฉด Effect๋ฅผ ํด๋ฆฐ์ ํด์ผ ํ๋ค๋ ์ฌ์ค์ ๋์น๊ธฐ ์ฌ์ ์ต๋๋ค. ๊ฐ๋ฐ ํ๊ฒฝ์์ Effect์ ๋ํด ์ ์ ๋์ ์ ์ โ ํด๋ฆฐ์ โ ์ ์ ์ ์คํํ๋ฉด Strict Mode์์ ๋๋ฝ๋ ํด๋ฆฐ์ ๋ก์ง์ด ๋ ๋์ ๋๊ฒ ๋ฉ๋๋ค.
Effect ํด๋ฆฐ์ ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์ธํ ์์๋ณด์ธ์.
Strict Mode์ ์ํด ํ์ฑํ๋ ์ฌ์ฉ ์ค๋จ ๊ฒฝ๊ณ ์์
React๋ <StrictMode>
ํธ๋ฆฌ ๋ด๋ถ์ ์ปดํฌ๋ํธ๊ฐ ๋ ์ด์ ์ฌ์ฉ๋์ง ์๋ ๋ค์ API ์ค ํ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๊ฒฝ๊ณ ๋ฅผ ํ์ํฉ๋๋ค.
findDOMNode
. ๋์ ๋ณด๊ธฐUNSAFE_componentWillMount
์ ๊ฐ์UNSAFE_
ํด๋์ค ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋. ๋์ ๋ณด๊ธฐ- ๋ ๊ฑฐ์ context (
childContextTypes
,contextTypes
, ๋ฐgetChildContext
). ๋์ ๋ณด๊ธฐ - ๋ ๊ฑฐ์ ๋ฌธ์์ด refs (
this.refs
). ๋์ ๋ณด๊ธฐ
์ด๋ฌํ API๋ ์ฃผ๋ก ์ด์ ํด๋์ค ์ปดํฌ๋ํธ์์ ์ฌ์ฉ๋๋ฏ๋ก ์ต์ ์ฑ์์๋ ๊ฑฐ์ ๋ํ๋์ง ์์ต๋๋ค.