๐ 2024. 04. 03 78์ผ์ฐจ
์ฝ๋ํ์์ ์ฌ์ฉํ TodoList์ ์ ์ฉ
ํ ์ผ ์ถ๊ฐ ํผ ๊ตฌํ
<form onSubmit={onSubmit}>
<input type="text" name="title" autoComplete="off" placeholder="ํ ์ผ ์
๋ ฅํด" />
<button type="submit">์ถ๊ฐ</button>
<button type="reset">์ทจ์</button>
</form>
github TodoList ์ ์ฉ, ํ ์ผ ์ถ๊ฐ ํผ
<form className="tw-flex tw-flex-col tw-p-4 tw-gap-2" onSubmit={onSubmit}>
<TextField name="content" autoComplete="off" label="ํ ์ผ์ ์
๋ ฅํด" variant="outlined" />
<Button className="tw-font-bold" variant="contained" type="submit">
์ถ๊ฐ
</Button>
</form>
github TODO ์ถ๊ฐ ํผ ๊พธ๋ฏธ๊ธฐ
ํ ์ผ ๊ฐฏ์ : {todosState.todos.length}
<nav>
<ul>
{todosState.todos.map((todo) => (
<li key={todo.id}>
<div className="tw-flex tw-flex-col tw-gap-2">
<span>๋ฒํธ : {todo.id}</span>
<span>๋ ์ง : {todo.regDate}</span>
<span>ํ ์ผ : {todo.content}</span>
</div>
</li>
))}
</ul>
</nav>
<nav>
<ul>
{todosState.todos.map((todo) => (
<li key={todo.id}>
<div className="tw-flex tw-flex-col tw-gap-2 tw-mt-[30px]">
<Chip label={`๋ฒํธ : ${todo.id}`} variant="outlined"></Chip>
<Chip label={`๋ ์ง : ${todo.regDate}`} variant="outlined"></Chip>
<Chip label={`ํ ์ผ : ${todo.content}`} variant="outlined" color="primary"></Chip>
</div>
</li>
))}
</ul>
</nav>
<div className="tw-p-10 tw-rounded-[20px] tw-shadow tw-whitespace-pre-wrap tw-leading-relaxed">
ํ ์ผ : {todo.content}
</div>
React.useEffect(() => {
todosState.addTodo('์ค์ฟผํธ');
todosState.addTodo('๋ฒค์น');
todosState.addTodo('๋ฐ๋');
}, []);
ํด๋น ์ด์๋ React 18 ์์ ๋์ ๋ strict mode ๊ธฐ๋ฅ์ ์ํด ๋ฐ์ํ๋ค. Next.js ์ ๊ฐ๋ฐ ํ๊ฒฝ์์๋ ์ด stirct mode ๊ฐ ํ์ฑํ๋์ด ์๋ค.
- strict mode๋?
strict mode ๋ ๊ฐ๋ฐ ํ๊ฒฝ์์ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ ์๊ฒฉํ๊ฒ ๊ฒ์ฌํ์ฌ ์์์น ๋ชปํ ๋ฒ๊ทธ๋ฅผ ์ฌ์ ์ ์ฐพ์๋ด๋ ๋ฐ์ ๋์์ ์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
์ด๋ฅผ ํ์ฑํ ํ๊ฒ ๋๋ฉด,
์ปดํฌ๋ํธ์ ๋ถ์์ ํ ๋ ๋๋ง์ ๊ฒ์ฌํ๊ธฐ ์ํด, ํ ๋ฒ ๋ ๋ ๋๋ง๋๋ค.
Effect ํด๋ฆฐ์ ํจ์๋ฅผ ์์ฑํ์ง ์์ ๋ฐ์ํ๋ ๋ฒ๊ทธ๋ฅผ ๊ฒ์ฌํ๊ธฐ ์ํด, Effect ๋ค์ ํ ๋ฒ ๋ ์คํํ๋ค.
์ปดํฌ๋ํธ์์ ๋ ์ด์ ์ฌ์ฉ๋์ง ์๋ API ๋ฅผ ์ฌ์ฉํ๋ ์ง ๊ฒ์ฌํ๋ค.
- ๊ฒฐ๋ก ์ ์ผ๋ก
ํด๋น ์ด์๊ฐ ๋ฐ์ํ ์์ธ์ด strict mode ๋๋ฌธ์์ ์ ์ ์๋ค.
strict mode ๋นํ์ฑ
๋นํ์ฑํ ์ ์ ์ํด์ผํ ์ ์ด ๋ช ๊ฐ์ง ์๋ค.
์ฐ์ , strict mode ๋ ๊ฐ๋ฐ ํ๊ฒฝ์์๋ง ๋์ํ๊ณ , ํ๋ก๋ํธ ๋ฐฐํฌ ํ๊ฒฝ์์๋ ๋์ํ์ง ์๋๋ค.
๋ํ, strict mode ๋ ์์ ํ๋ฏ ์๊ธฐ์น ๋ชปํ ๋ฒ๊ทธ๋ค์ ์ฐพ์๋ด๋ ๋ฐ์ ๋์์ ์ค๋ค.
๋ฐ๋ผ์, ๊ฐ๋ฐ ํ๊ฒฝ์์ ํ์์ ์ผ๋ก ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํ๋ ์ํฉ์ด ์๋๋ผ๋ฉด, ๊ตณ์ด strict mode ๋ฅผ ๋นํ์ฑํ ํ ํ์๋ ์๋ค. ์ด์ฐจํผ ๋ฐฐํฌ ํ๊ฒฝ์์๋ ์ํ๋ ๋๋ก Effect ๊ฐ ํ ๋ฒ๋ง ํธ์ถ๋๋ค.
// next.config.js
const nextConfig = {
reactStrictMode: false,
};
module.exports = nextConfig;
next.config.js ํ์ผ์ ์์ ๊ฐ์ด ์์ ํ๋ฉด ๋นํ์ฑํ ๋!
<TextField
multiline
minRows={3}
maxRows={10}
name="content"
autoComplete="off"
label="ํ ์ผ์ ์
๋ ฅํด"
variant="outlined"
/>
<Box sx={{ color: 'primary.main' }}>{todo.content}</Box>
const theme = createTheme({
palette: {
typocraphy: {
fontFamily: ['GmarketSansMedium'],
},
type: 'dark',
primary: {
main: '#2196f3',
light: 'rgb(77, 171, 245)',
dark: 'rgb(23, 105, 170)',
contrastText: '#fff',
},
secondary: {
main: '#f50057',
},
},
});
color: 'primary.main'
์์ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉ๊ฐ๋ฅ
github Chip ์๋จ ์ฌ๋ฐฑ, Box sx, theme light,dark
setTodos((todos) => [...todos, newTodo]);
newTodo๊ฐ ์์ผ๋ก ๋จผ์ ๋ณด์ด๊ฒ ๋ฐ๊พธ๋ฉด ๋ ๋ฏ
setTodos((todos) => [newTodo, ...todos]);
- MUI์์ theme color์ ๋ฝ์์์ CSS์์ ํ์ฉํ ์ ์๋๋ก ํด๋ณด์!!
React.useEffect(() => {
const r = document.querySelector(':root');
muiThemePaletteKeys.forEach((paletteKey) => {
const themeColorObj = theme.palette[paletteKey];
// console.log(themeColor);
for (const key in themeColorObj) {
// console.log(key);
if (Object.hasOwnProperty.call(themeColorObj, key)) {
const colorVal = themeColorObj[key];
r.style.setProperty(`--mui-color-${paletteKey}-${key}`, colorVal);
}
}
});
}, []);
useEffect ๋ด์์ ์ฝ๋๋ HTML ๋ฌธ์์ :root ์์๋ฅผ ์ ํ.
muiThemePaletteKeys ๋ฐฐ์ด์๋ MUI ํ๋ ํธ์ ๋ค์ํ ๋ถ๋ถ์ ํด๋นํ๋ ํค๊ฐ ํฌํจ๋์ด ์๋ค.
forEach ๋ฃจํ๋ muiThemePaletteKeys ๋ฐฐ์ด์ ๊ฐ ํค๋ฅผ ๋ฐ๋ณต.
๊ฐ ํค์ ๋ํด ์ฝ๋๋ ํ ๋ง ํ๋ ํธ ๊ฐ์ฒด์์ ์์ ๊ฐ์ ๊ฒ์ํ๊ณ setProperty ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฅผ CSS ๋ณ์๋ก ์ค์ . ์ด๋ฅผ ํตํด CSS ์คํ์ผ์ํธ์์ ์ด๋ฌํ ์์์ ์ฌ์ฉํ ์ ์๋ค.
tw-text-[--mui-color-warning-main]
์ด๋ฐ์์ผ๋ก ์ฌ์ฉ๊ฐ๋ฅ!!
github mui theme color๋ค์ CSS์์ ํ์ฉํ ์ ์๋๋ก CSS ๋ณ์ํ
์ฌ์ฉ์ ์ง์ ์์ฑ(CSS ๋ณ์, ์ข ์ ๋ณ์)์ CSS ์ ์์๊ฐ ์ ์ํ๋ ๊ฐ์ฒด๋ก, ๋ฌธ์ ์ ๋ฐ์ ์ผ๋ก ์ฌ์ฌ์ฉํ ์์์ ๊ฐ์ ๋ด๋๋ค. ์ฌ์ฉ์ ์ง์ ์์ฑ์ ์ ์ฉ ํ๊ธฐ๋ฒ์ ์ฌ์ฉํด ์ ์ํ๊ณ , (--main-color: black;) var() ํจ์๋ฅผ ์ฌ์ฉํด ์ ๊ทผํ ์ ์๋ค. (color: var(--main-color);)
๋ณต์กํ ์น์ฌ์ดํธ ๊ฐ์ ๊ฒฝ์ฐ ์์ฒญ๋ ์์ CSS๋ฅผ ๊ฐ์ง๊ณ ์๋๋ฐ, ์ ์ง๋ณด์๋ฅผ ํ๋ค ๋ณด๋ฉด ์ฌ๋ฌ ๊ณณ์์ ์ฌ์ฉํ ์์์ ๊ฐ์ ํ๊บผ๋ฒ์ ๋ฐ๊ฟ์ผ ํ ๋๊ฐ ์๋ค. ๊ทธ ๊ฐ๋ค์ ํ๋์ฉ ์ฐพ์์ ์ผ์ผ์ด ๋ฐ๊พธ๋ ค๋ฉด ์๋นํ ํผ๊ณคํ ๊ฒ์ด๊ณ , ๋์ ๋ฐ๋ผ ์ค์๋ ๋ง์ ๊ฒ์ด๋ค.
๊ทธ๋์ ์ฌํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ฒ๋ผ ๋ณ์๋ฅผ ์ด์ฉํ๋ฉด, ์์ ์ ๋ฐ์ ๊ฑธ์ณ ์ฌ์ฉ๋๋ ์์์ ๊ฐ์ ๋ณ์์ ์ ์ฅํ๊ณ ํธ์ถํ๋ฉด ๋ณด๋ค ํจ์จ์ ์ธ ํ๋ก๊ทธ๋๋ฐ์ด ๊ฐ๋ฅํด์ง๋ค.
:root {
--main-font-color: #000f22; /* CSS ์ ์ญ ๋ณ์ ์ ์ธ */
}
div {
color: var(--main-font-color); /* CSS ๋ณ์ ์ฌ์ฉ */
}