# ์ํ ๋ฏน ๋์์ธ ์ ์ฌ์ฉํ๊ณ ์ถ์์ง?
ํ ํ๋ก์ ํธ์์ pages, components ํด๋๋ก ๋๋๊ณ ๊ณตํต์ผ๋ก ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ค์ components ํด๋์, ํด๋น ํ์ด์ง์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ค์ ํ์ด์ง ํด๋์์ ๊ด๋ฆฌํ๋๋ก ํ์๋ค. ์ํ ๋ฏน ๊ตฌ์กฐ๋ฅผ ์ ์ฉํ๊ณ ์ถ์์ง๋ง, ์ ์ฉํ์ง ๋ชปํ๋๋ฐ ๊ทธ ์ด์ ๋
1. ํผ๊ทธ๋ง๊ฐ ์๋ฒฝํ ๋์ง ์์ ์ํ, ๊ทธ๋ฆฌ๊ณ ๊ณ์ ๊ตฌํํ๋ฉด์ ๋ณ๊ฒฝ๋ ํ๋ฅ ์ด ๋์.
-> ์๊ฒ ์ชผ๊ฐ๋ ๋ฐฉ์์ธ ์ํ ๋ฏน ๊ตฌ์กฐ๋ฅผ ์ ์ฉํ๊ธฐ์๋ ์ด๋ ค์์ด ์๊ธธ ๊ฒ ๊ฐ์ ์๊ฐ์ด ๋ค์๋ค.
2. ๊ฐ์ธ ํ๋ก์ ํธ๊ฐ ์๋ ํ ํ๋ก์ ํธ, ์ ํด์ง ๊ธฐ๊ฐ ๋ด์ ํ๋ก์ ํธ ๋ง๋ฌด๋ฆฌ.
-> ๊ตฌ์กฐ์ ์ธ ์ธก๋ฉด์ ์๊ฐ์ ์๋ ๊ฒ๋ณด๋ค ๋ค๋ฅธ ์ฝ๋ ๋ถ๋ถ์ ์ง์คํ๋ ๊ฒ์ด ๋ง๋ค๋ ์๊ฐ์ด ๋ค์๋ค.
์ด๋ฌํ ์ด์ ๋ก ๊ณผํ ์๋ ์์ง๋ง, TodoApp์ ์ ์ฉํด๋ณด๊ธฐ๋ก ํ์๋ค!
# ์ํ ๋ฏน ๋์์ธ
์ํ ๋ฏน ๋์์ธ ์ ํํ์ ๊ด์ ์์ ์๊ฐ์ ์ป์ ๋์์ธ ์์คํ ์ผ๋ก ์์์์ ๋ถ์ , ๋ถ์์์ ์ ๊ธฐ์ฒด, ๊ถ๊ทน์ ์ผ๋ก ๋ฌผ์ง๋ก ๊ตฌ์ฑ๋๋ ์ด๋ฐ ํํ์ ๊ด์ ์์ ์๊ฐ์ ์ป์๋ค๊ณ ํ๋ค.
์ํ ๋ฏน ๋์์ธ์ ์ด ๋ค์ฏ ๊ฐ์ง์ ๋จ๊ณ๋ก ์ปดํฌ๋ํธ๋ฅผ ๊ด๋ฆฌํ๋ค.
1. Atom : ๋ ์ด์ ๋ถํดํ ์ ์๋ ๊ธฐ๋ณธ ์ปดํฌ๋ํธ. (ex : button, input, text... )
2. Molecules : ์ฌ๋ฌ ๊ฐ์ atom์ ๊ฒฐํฉ. (ex button ๊ณผ input ๊ฒฐํฉํ search ์ปดํฌ๋ํธ )
3. Organisms : Molecules ๊ณผ Atom๋ค์ ์กฐํฉํ ์ปดํฌ๋ํธ.
4. Templates : ์ค์ ์ปดํฌ๋ํธ๋ฅผ ๋ ์ด์์์ ๋ฐฐ์นํ๊ณ ๊ตฌ์กฐ๋ฅผ ์ก๋ ์์ด์ด ํ๋ ์.
5. Pages : ์ค์ ํ์ด์ง.
# Todo ์ ์ ์ฉํด๋ณด์!
## ๐ค ๊ณ ๋ฏผ Todo ์ ๋ชจ๋ ๋จ๊ณ๋ฅผ ์ ์ฉํด์ผ ํ ๊น?
์ฌ์ค Todo ์์ฒด๋ Atom ๋์์ธ์ ์ ์ฉํ๋ ๊ฒ์ด ๋ง์ด ๊ณผํ๊ธฐ์.. ๋ชจ๋ ๋จ๊ณ๋ฅผ ์ ์ฉํ ํ์๊ฐ ์๋์ง์ ๋ํ ๊ณ ๋ฏผ์ด ์๊ฒผ๋ค.
๊ทธ๋์ ๊ณ ๋ฏผ ๋์ organisms ๋จ๊ณ๋ฅผ ์ ์ธํ๊ณ ์ ์ฉํด๋ณด๊ธฐ๋ก ํ์๋ค!
## โ๏ธ ์ ์ฉ
### Atoms
TodoApp ํ์ด์ง๋ ์ด 6๊ฐ๋ค. (๋๋ฉ / ํ์๊ฐ์ / ๋ก๊ทธ์ธ / Todos / ์์ธ Todo / Todo ์์ฑ )
ํ์ด์ง์ ์ฌ์ฉ๋๋ ์ปดํฌ๋ํธ๋ค์ ๋ชจ๋ atoms ์ผ๋ก ๊ตฌ๋ถํ์ง ์๊ณ , ๊ณตํต์ผ๋ก ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ค๋ง Atoms ํด๋์ ๊ตฌํํ์๋ค.
๊ทธ๋ฆฌ๊ณ styled-components ๋ฅผ ์ฌ์ฉํด์ ๋ฐ์์จ props.type ๋ณ๋ก style์ ์ ์ฉํ์ฌ ์ฌ์ฌ์ฉ์ฑ์ ๋์ผ ์ ์์๋ค!
const ButtonWrapper = styled.button<{ btnType: string }>`
width: ${(props) => (props.btnType === 'home' ? '50px' : '100px')};
height: ${(props) => (props.btnType === 'home' ? '50px' : '40px')};
background-color: ${(props) => {
switch (props.btnType) {
case 'add':
return '#0a86f7';
case 'logout':
return 'white';
case 'delete':
return '#e7f5ff';
default:
return '#0a86f7';
}
}};
color: ${(props) => {
switch (props.btnType) {
case 'logout':
return '#228be6';
case 'delete':
return '#228be6';
default:
return 'white';
}
}};
border: none;
border-radius: ${(props) => (props.btnType === 'home' ? '50%' : '10px')};
cursor: pointer;
`;
interface TitleProps {
title: string;
type: string;
}
const Title = ({ title, type }: TitleProps) => {
return <TitleWrapper type={type}>{title}</TitleWrapper>;
};
export default Title;
const TitleWrapper = styled.h1<{ type: string }>`
font-size: ${(props) => (props.type === 'card' ? '20px' : '30px')};
`;
### Molecules
Molecules ํด๋๋ todo ํด๋์ user ํด๋๋ก ๋๋์ด ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ค์ ๊ตฌํํ์๋ค.
Molecules๋ก ๋๋๋ ๊ธฐ์ค์ Atoms ๊ฐ ๋ ๊ฐ ์ด์ ํฌํจ๋๊ณ , ์ต์ํ ํ๋ ์ด์์ ๊ธฐ๋ฅ์ ์ํํ๋๋ก ๊ตฌํํ์๋ค.
๋, ์ฌ์ฌ์ฉ์ ํ ์ ์๋์ง ๊ณ ๋ คํด์ , ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋๋ก ๊ตฌํํ์๋๋ฐ ์๋ฅผ ๋ค์ด ํ์๊ฐ์ ํ์ด์ง์ ๋ก๊ทธ์ธ ํ์ด์ง์์ input๊ณผ button์ผ๋ก ๊ตฌ์ฑ๋์๊ธฐ ๋๋ฌธ์ ๊ณตํต ์ปดํฌ๋ํธ๋ก ๊ตฌํํ์๋๋ฐ, page์์ AccountForm์ url์ props๋ก ์ ๋ฌํด์ url์ ๋ฐ๋ผ ํ์ ๊ฐ์ or ๋ก๊ทธ์ธ์ผ๋ก ๊ตฌ๋ณํด์ post ์์ฒญ์ ๋ณด๋ด๋ ๋ฐฉ์์ผ๋ก ํด๋ณด์๋ค. (-> ์ด ๋ฐฉ๋ฒ์ด ๊ด์ฐฎ์ ๊ฒ์ธ์ง.. ์ ๋ชจ๋ฅด๊ฒ ๋ค..)
const onClick = async () => {
if (url == 'create') {
try {
await instance.post(`/users/${url}`, {
email: account.email,
password: account.password,
});
navigate('/signin');
} catch (err) {
if (err instanceof Error) {
SnackBar(err.message, 'error');
}
}
} else {
try {
const res = await instance.post(`/users/${url}`, {
email: account.email,
password: account.password,
});
window.localStorage.setItem('token', res.data.token);
setLoginState(true);
navigate('/todolist');
} catch (err) {
if (err instanceof Error) {
SnackBar(err.message, 'error');
}
}
}
};
### Template
๋ ์ด์์! Todo ์์ฑ / ๋ฆฌ์คํธ / ์์ธ๋ณด๊ธฐ์์ ์ ์ฉ๋๋ ๋ ์ด์์์ด ๋ชจ๋ ๋๊ฐ๊ธฐ ๋๋ฌธ์ ํ๋ฒ ๋ง๋ค์ด ๋ณด์๋ค.
import React from 'react';
import styled from 'styled-components';
const Template = ({ children }: { children: React.ReactNode }) => {
return <Container>{children}</Container>;
};
export default Template;
const Container = styled.div`
display: grid;
justify-items: center;
padding-top: 60px;
`;
return (
<Template>
<TodoHeader />
<TodoCreateForm />
</Template>
);
### Pages
# ์์ฌ์ด ์ = ๋ถ์กฑํ ์ = ์ ์ํ ์
1. ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ์ฑ์ด ๋์์ก์ผ๋, Props Drilling ์ด ์์นซํ๋ฉด ๋ง์์ง ์ ์์ด์ ์ฃผ์ํ๋ฉด์ ์ฌ์ฉํด์ผ ํ ๊ฒ ๊ฐ๋ค.
-> ์ด ๋ถ๋ถ์ ์ฃผ์ํ๊ธฐ ์ํด ๋ชจ๋ ์ปดํฌ๋ํธ๋ฅผ atoms ๋ก ๊ตฌ๋ถํ์ง ์๊ณ , ๊ณตํต์ ์ผ๋ก ๋ง์ด ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ค๋ง atoms ํด๋์ ๋ฐ๋ก ๊ตฌํํ์๋ค. ๋ค๋ง ์ด๋ฐ ๋ถ๋ถ๋ ์ฃผ๊ด์ ์ธ ๊ธฐ์ค์์ ๋ถ๋ฆฌํ ๊ฒ์ด๊ธฐ์, ์ํ๋ค๊ณ ๋ ํ์คํ ์ ์๋ค.
2. ๋จ๊ณ๋ณ ๋ถ๋ฆฌ ๊ธฐ์ค.
-> Atoms ์ ๊ตฌ๋ถํ๋ ๋ฐ ์์ด์๋ ์ด๋ ต์ง ์์์ง๋ง, molecules์ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌํํ๋ ๊ธฐ์ค์ ์ ํ๋ ๊ฒ์ ์์ด์ ์ด๋ ค์์ด ์์๋ค.
์ผ๋จ Atoms ์ปดํฌ๋ํธ๊ฐ 2๊ฐ ์ด์ ๋ค์ด์๊ณ , ๋๋ฆ์ ๊ธฐ์ค์ผ๋ก ํ๋์ ๊ธฐ๋ฅ์ ์ํ! ์ ๊ธฐ์ค์ผ๋ก ๊ตฌํํ๊ธด ํ๋๋ฐ, TodoApp ์ ๊ตฌ์ฑ ์์ฒด๊ฐ ๊ฐ๋จํ๊ณ Organisms ๋จ๊ณ๋ฅผ ์ ์ธํ๊ธฐ ๋๋ฌธ์ ๊ทธ๋๋ง ๊ด์ฐฎ์๋ค. ๋ง์ฝ ํํ๋ก์ ํธ ๊ฐ์ ๋ณต์กํ ๊ตฌ์กฐ์์ Organisms ๋จ๊ณ๋ฅผ ํฌํจ์์ผฐ๋ค๋ฉด, Molecules์ Organisms๋ฅผ ๋ถ๋ฆฌํ๊ธฐ ์ํ ๊ธฐ์ค์ ์ ํ๊ธฐ ์ํด ์์ฒญ๋... ๊ณ ๋ฏผ์ ํ์ ๊ฒ ๊ฐ๋ค.
๋ง์ง๋ง์ผ๋ก ํ ํ๋ก์ ํธ์์ ์ํ ๋ฏน ๊ตฌ์กฐ๋ฅผ ์ ์ฉํ์ง ๋ชปํด์ ๊ถ๊ธ์ฆ๋ง ์ปค์ ธ๊ฐ๋๋ฐ, ์์ Todo ํ๋ก์ ํธ์ง๋ง ์ด๋ ๊ฒ ์ ์ฉํด๋ณด๊ณ ์ํ ๋ฏน ๊ตฌ์กฐ์ ์ฅ๋จ์ ์ ์ฒด๊ฐํ๊ณ ๊ถ๊ธ์ฆ์ด ํด์๋์๋ค! ๐ ๋ง์ฝ ๋ค์์ ์ํ ๋ฏน ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ ์ผ์ด ์๊ธด๋ค๋ฉด, ์ง๊ธ ๋๋ ์ฅ๋จ์ ์ ๊ธฐ์ตํ๋ฉด์! ์ต๋ํ ๋จ์ ์ ์ค์ผ ์ ์๋๋ก ๋ ธ๋ ฅํ์ !
'๐ WIL > ๐ React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Scroll ์ด๋ฒคํธ ๋์ Intersection Observer API ์ด์ฉํ์! (0) | 2022.08.24 |
---|---|
React Query (์ด์ TanStack Query ๋ผ๊ณ ๋ถ๋ฆฌ๋ ..) ์ ์ฉ (1) (0) | 2022.08.19 |
โ๏ธ useRef (0) | 2022.08.10 |
โ๏ธ useMemo, useCallback (+ React.memo + HOC) (0) | 2022.08.10 |
๐ก useContext ๋ฅผ ๋ง์ด ์ฐ๋ฉด ์๋๋ค...? (0) | 2022.08.10 |