React๋ ๊ฐ๋ฐ์๊ฐ ์์ ๋กญ๊ฒ ์ปดํฌ๋ํธ๋ฅผ ์งค ์ ์๊ธฐ ๋๋ฌธ์, ๋ค์ํ ํจํด๋ค์ด ์กด์ฌํ๋ค. ๊ทธ ์ค์์ ๋ํ์ ์ธ ์ปดํฌ๋ํธ ํจํด์ ์์๋ณด์.
Container Component
์์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ Presentational Component
์์ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ๋ ํจํด์ด๋ค.
์ปดํฌ๋ํธ๋ฅผ ๋๋๋ ์ด์ ๊ฐ ๋ฌด์์ผ๊น?? ๐ค
ํ๋์ ์ปดํฌ๋ํธ์ api ํธ์ถ, ์ด๋ฒคํธ ํจ์, ๋น์ฆ๋์ค ๋ก์ง, ์ํ๊ด๋ฆฌ๊ฐ ๋ชจ๋ ๋ด๊ฒจ์์ผ๋ฉด ์ปดํฌ๋ํธ๊ฐ ๋น๋ํด์ ธ์ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ง๋ค. ๊ทธ๋์ UI
์ ๋ก์ง์ ๊ฐ๊ฐ Presentational Component
์ Container Component
๋ก ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ๋ค.
์์
// Before
// src/components/Login/LoginForm.js
const LoginForm = () => {
const [form, setForm] = useState({
email: "",
password: "",
});
const { email, password } = form;
const onChange = (e) => {
const { name, value } = e.target;
setForm({
...form,
[name] : value,
});
}
const onSubmit = (e) => {
e.preventDefault();
console.log(form);
}
return (
<form onSubmit={onSubmit}>
<div>
<label>์ด๋ฉ์ผ</label>
<input type="text" value={email} name="email" onChange={onChange}/>
</div>
<div>
<label>๋น๋ฐ๋ฒํธ</label>
<input type="password" value={password} name="password" onChange={onChange}/>
</div>
<button type="submit">๋ก๊ทธ์ธ</button>
</form>
);
}
export default LoginForm;
// After
// src/components/Login/LoginForm.container.js
const LoginFormContainer = () => {
const [form, setForm] = useState({
email: "",
password: "",
});
const { email, password } = form;
const onChange = (e) => {
const { name, value } = e.target;
setForm({
...form,
[name] : value,
});
}
const onSubmit = (e) => {
e.preventDefault();
console.log(form);
}
return (
<LoginForm email={email} password={password} onChange={onChange} onSubmit={onSubmit}/>
);
}
export default LoginFormContainer;
// src/components/Login/LoginForm.presenter.js
const LoginForm = ({ email, password, onChange, onSubmit }) => {
return (
<form onSubmit={onSubmit}>
<div>
<label>์ด๋ฉ์ผ</label>
<input type="text" value={email} name="email" onChange={onChange}/>
</div>
<div>
<label>๋น๋ฐ๋ฒํธ</label>
<input type="password" value={password} name="password" onChange={onChange}/>
</div>
<button type="submit">๋ก๊ทธ์ธ</button>
</form>
);
}
export default LoginForm;
Redux ์ฐฝ์์์ธ Dan Abramov๋ ๋ ์ด์ ์ด ํจํด์ ์ด์ฉํ์ง ์๋๋ค๊ณ ํ๋ค.
Component & Hooks
ํจํด์ผ๋ก ๋์ฒด๊ฐ ๊ฐ๋ฅํ๊ณ , ์ด ํจํด์ UI๋ฟ๋ง ์๋๋ผ ๋ก์ง๊น์ง ์ฌํ์ฉ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
๐ ์ฐธ๊ณ - Presentational and Container Components
Container Component
๋์ Hook
์์ ๊ด๋ฆฌํ๋ค.Container Component
๋ฅผ ์ฌ์ฉํ๋ฉด ๊ณตํต ๋ก์ง์ด ๋ฐ์ํ์ ๋ ๋ก์ง์ ๋๊ฒจ์ฃผ์ง ๋ชปํ์ง๋ง, Hook
์์ ์ปดํฌ๋ํธ ๋ก์ง์ ๊ด๋ฆฌํ๋ฉด ๋ก์ง ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํด์ง๋ค.์์
// src/components/Login/LoginForm.js
const LoginForm = () => {
const { form, onChange, onSubmit } = useLogin();
const { email, password } = form;
return (
<form onSubmit={onSubmit}>
<div>
<label>์ด๋ฉ์ผ</label>
<input type="text" value={email} name="email" onChange={onChange}/>
</div>
<div>
<label>๋น๋ฐ๋ฒํธ</label>
<input type="password" value={password} name="password" onChange={onChange}/>
</div>
<button type="submit">๋ก๊ทธ์ธ</button>
</form>
);
}
export default LoginForm;
// src/components/Login/useLogin.js
const useLogin = () => {
const [form, setForm] = useState({
email: "",
password: "",
});
const { email, password } = form;
const onChange = (e) => {
const { name, value } = e.target;
setForm({
...form,
[name] : value,
});
}
const onSubmit = (e) => {
e.preventDefault();
console.log(form);
}
return { form, onChange, onSubmit };
}
export default useLogin;
๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ Atom
๋จ์์์ ์์ํ์ฌ ํ๋์ฉ ๊ฒฐํฉํ๋ ํจํด์ ๋งํ๋ค.
props drilling
์ ํตํด ์ ๋ฌ๋๋ค.Atom
input
, button
๊ณผ ๊ฐ์ HTML ํ๊ทธ๋ ์ต์ ๊ธฐ๋ฅ์ ๊ฐ์ง ๊ฐ์ฅ ์์ ๋จ์์ ์ปดํฌ๋ํธ๋ฅผ ๋งํ๋ค.
Molecules
Atom
๋ค์ด ์ต์์ ์ญํ ์ ์ํํ ์ ์๋๋ก ์กฐํฉํ ์ปดํฌ๋ํธOrganisms
layout
๋จ์๋ก Molecules
๊ณผ Atom
์ ์กฐํฉํ ์ปดํฌ๋ํธTemplates
Organisms
๋ฅผ ์กฐํฉํ์ฌ ํ๋์ ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ๋ ์ปดํฌ๋ํธclass
์ ๋น์ทํ๋ค.Pages
Template
์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ ์ปดํฌ๋ํธ๐ ๋ฆฌ์กํธ์๋ ๋ค์ํ ์ปดํฌ๋ํธ ํจํด์ด ์์ง๋ง, ๊ทธ ์ค์์ ์ ๋ต์ ์๋ค. ๊ฐ๊ธฐ ๋ค๋ฅธ ํ๋ก์ ํธ ํ๊ฒฝ์ ๋ง๋ ์ปดํฌ๋ํธ ํจํด์ ์ ํํด์ผ ํ๊ณ , ๋ํ ํ์๋ค์ ๊ฒฝํ์ ๊ณ ๋ คํ์ฌ ์ ํฉํ ์ปดํฌ๋ํธ ํจํด์ ์ ํํด์ผ ํ๋ค!!