2025. 10. 20. 11:28ใReact
์ด๋ฒ ์์ ์์๋ ํ์๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ ๊ณผ์ ์์ ๋ฐ์ํ ์ฌ๋ฌ ๋ฌธ์ ๋ฅผ ์ ๋ฆฌํ๊ณ , ํด๊ฒฐ ๋ฐฉ๋ฒ ๋ฐ ์ฝ๋ ๋ฆฌํฉํ ๋ง ์งํํ์์ต๋๋ค.
1. ํ์๊ฐ์ ๊ธฐ๋ฅ ๊ตฌํ
โ ์ฃผ์ ๊ตฌํ ๋ด์ฉ
- ๋น๋ฐ๋ฒํธ ์ ํจ์ฑ ๊ฒ์ฌ
- ๋น๋ฐ๋ฒํธ ์ ๋ ฅ๊ฐ์ด ๋น์ด ์์ผ๋ฉด “๊ฐ์ ์ ๋ ฅํ์ธ์” ์๋ฌ ์ถ๋ ฅ
- ์ ๋ ฅ์ด ๋์ด ์๋ ์ํ๋ผ๋ฉด “ํ์ ์ค๋ฅ” ์๋ฌ ์ถ๋ ฅ
- ์์ด๋ ์ค๋ณต ํ์ธ
- “์ค๋ณต ํ์ธ” ๋ฒํผ ํด๋ฆญ ์, ์๋ฒ์์ ํด๋น ์์ด๋์ ์กด์ฌ ์ฌ๋ถ ํ์ธ
- ์ด๋ฏธ ์กด์ฌํ๋ฉด “์ด๋ฏธ ์กด์ฌํ๋ ์์ด๋์ ๋๋ค” ๋ฉ์์ง ํ์
- ์กด์ฌํ์ง ์์ผ๋ฉด “์ฌ์ฉ ๊ฐ๋ฅํ ์์ด๋์ ๋๋ค” ๋ฉ์์ง ํ์
- ๋น๋ฐ๋ฒํธ ์ํธํ ์ฒ๋ฆฌ
- ๋น๋ฐ๋ฒํธ ์ ๋ ฅ ํ๋๋ฅผ ๋จ์ผํํ๊ณ , ๋ด๋ถ์ ์ผ๋ก ๋น๋ฐ๋ฒํธ์ ๋น๋ฐ๋ฒํธ ํ์ธ ํ๋ ๋ชจ๋ ์ํธํ ์ฒ๋ฆฌ
- ํ์๊ฐ์
๊ฒฝ๋ก๋ณ Role ๊ตฌ๋ถ
- ์์ฌ์ฉ/์ผ๋ฐ ์ฌ์ฉ์์ฉ ํ์๊ฐ์
ํ์ด์ง๊ฐ ๋ถ๋ฆฌ๋์ด ์์ผ๋ฏ๋ก
location.path๋ก ํ์ฌ ๊ฒฝ๋ก๋ฅผ ๋ฐ์ role ๊ฐ์ ์ค์ ํ ๋ค ๋ฐฑ์๋๋ก ์ ๋ฌ
- ์์ฌ์ฉ/์ผ๋ฐ ์ฌ์ฉ์์ฉ ํ์๊ฐ์
ํ์ด์ง๊ฐ ๋ถ๋ฆฌ๋์ด ์์ผ๋ฏ๋ก
2. ๊ตฌํ ์ค ๋ฐ์ํ ๋ฌธ์
โ ๏ธ ๋ฌธ์ 1. ์ฒดํฌ๋ฐ์ค ์ค๋ณต ๋ฐ์
๋ก๊ทธ์ธ๊ณผ ํ์๊ฐ์
ํ์ด์ง์์ ๋ชจ๋ “๋น๋ฐ๋ฒํธ ๋ณด๊ธฐ” ๊ธฐ๋ฅ์ ๊ตฌํํ๋ฉด์,
๊ฐ์ CheckBox ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ค ๋ณด๋ state ์ถฉ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์์ธ
- ๋ ํ์ด์ง๊ฐ ๋์ผํ ์ปดํฌ๋ํธ๋ฅผ importํ๋ฉด์ ๋์ผํ ์ํ(state)๋ฅผ ๊ณต์ ํ ๊ฐ๋ฅ์ฑ ์กด์ฌ
ํด๊ฒฐ
- ๊ฐ ํ์ด์ง ๋ด์์ ๋ ๋ฆฝ์ ์ธ ์ํ๋ฅผ ๊ด๋ฆฌํ๋๋ก ์์
- ์ฒดํฌ๋ฐ์ค ์ปดํฌ๋ํธ๋ฅผ ๋ณ๋ ํ์ผ๋ก ๋ถ๋ฆฌํ๊ณ , ๊ฐ ํ์ด์ง์์ show ์ํ๋ฅผ ์ ์ธ ํ props๋ก ์ ๋ฌ
โ ์์ ๋ CheckBox ์ปดํฌ๋ํธ
function CheckBox({ boxName, show, setShow }) {
return (
<label className="flex items-center mx-5">
<input
name={boxName}
type="checkbox"
className="mx-2"
checked={show}
onChange={(e) => setShow(e.target.checked)}
/> {boxName}
</label> );
}
export default CheckBox;
์ ์ฉ ์์
function CheckBox({ boxName, show, setShow }) {
return (
<label className="flex items-center mx-5">
<input
name={boxName}
type="checkbox"
className="mx-2"
checked={show}
onChange={(e) => setShow(e.target.checked)}
/> {boxName}
</label> );
}
export default CheckBox;
3. ์์ธ ์ฒ๋ฆฌ ๋ก์ง ๊ฐ์
์ด๊ธฐ ๊ตฌํ์์๋ ํ์๊ฐ์
์์ฒญ ์ ๋ฐ์ํ๋ ์๋ฌ ์ฒ๋ฆฌ ์ฝ๋๊ฐ ์ง๋์น๊ฒ ๊ธธ๊ณ ๋ณต์กํ์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ์๋ฌ ์ฒ๋ฆฌ ์ ์ฉ ํจ์๋ฅผ ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ๋๋ก ๋ฆฌํฉํ ๋งํ์ต๋๋ค.
๊ธฐ์กด ์ฝ๋ (๋ณต์กํ ํํ)
fetchSignUp(signUpInfo)
.then((res) => {
localStorage.setItem("accessToken", res.data.token.trim());
setErrors(initialErrors);
navigate("/");
})
.catch((err) => {
const errorMessages = err.response?.data;
const Errors = {};
if (err.response?.status === 409 || err.response?.status === 401) {
if (errorMessages.includes("์์ด๋")) {
Errors.loginIdError = errorMessages;
}
if (errorMessages.includes("๋น๋ฐ๋ฒํธ")) {
Errors.checkPasswordError = errorMessages;
}
}
if (err.response?.status === 400) {
errorMessages.forEach((element) => {
if (element.includes("์์ด๋")) Errors.loginIdError = element;
if (element.includes("๋น๋ฐ๋ฒํธ")) {
if (e.target.password.value === "" && element.includes("ํ์")) {
Errors.passwordError = element;
}
if (e.target.password.value !== "" && element.includes("ํ์")) {
Errors.passwordError = element;
}
}
if (element.includes("๋น๋ฐ๋ฒํธ") && element.includes("์ฌ์
๋ ฅ")) {
Errors.checkPasswordError = element;
}
if (element.includes("์ด๋ฆ")) Errors.nameError = element;
if (element.includes("์ด๋ฉ์ผ")) {
if (e.target.email.value === "" && element.includes("ํ์")) {
Errors.emailError = element;
}
if (e.target.email.value !== "" && element.includes("ํ์")) {
Errors.emailError = element;
}
}
});
}
setErrors((prev) => ({ ...prev, ...Errors }));
});
๊ฐ์ ๋ ์ฝ๋ (ํจ์ ๋ถ๋ฆฌ)
fetchSignUp(signUpInfo)
.then((res) => {
localStorage.setItem("accessToken", res.data.token.trim());
setErrors(initialErrors);
navigate("/");
})
.catch((err) => {
const errorMessages = err.response?.data;
let errors = {};
if (err.response?.status === 409 || err.response?.status === 401) {
errors = handleError(errorMessages);
}
if (err.response?.status === 400) {
errors = handleValidationError(errorMessages, isPasswordEmpty, isEmailEmpty);
}
setErrors((prev) => ({ ...prev, ...errors }));
});
4. ์ ๋ ฅ ํผ ๊ตฌ์กฐ์ ๋ํ ๊ณ ๋ฏผ
ํ์ฌ ๋ก๊ทธ์ธ๊ณผ ํ์๊ฐ์
ํ์ด์ง๋ ๋์ผํ ์
๋ ฅ ํผ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
- ํ์๊ฐ์ ์์๋ ์์ด๋ ์ค๋ณต ํ์ธ ๋ฒํผ, ๋น๋ฐ๋ฒํธ ๋ณด๊ธฐ ์ฒดํฌ๋ฐ์ค ๋ฑ ์ถ๊ฐ ์์ ํ์
- ๋ก๊ทธ์ธ ํผ์ ๊ฐ๋จํ์ง๋ง ํ์๊ฐ์ ์ ๊ธฐ๋ฅ์ด ๋ง์ ๊ณตํต ์ปดํฌ๋ํธ๋ก ๊ด๋ฆฌ ์ ๋ณต์ก๋๊ฐ ์ฆ๊ฐ
๊ฒฐ๋ก
๊ณตํต ์ปดํฌ๋ํธ๋ก ์ ์งํ๊ธฐ๋ณด๋ค๋,๊ธฐ๋ณธ ์
๋ ฅ ํผ(BaseForm)์ ๊ณตํต์ผ๋ก ๋๊ณ
๋ก๊ทธ์ธ/ํ์๊ฐ์
ํ์ด์ง๋ณ๋ก ํ์ํ ์ถ๊ฐ ์์๋ฅผ ํ์ฅํ๋ ๋ฐฉ์์ด ์ ์ ํ๋ค๊ณ ํ๋จํ์ต๋๋ค.
5. ํด๋ ๊ตฌ์กฐ ๊ฐ์ ์ ์
ํ์ฌ components ํด๋ ์์ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๋ค์ด์๋๋ฐ ๊ณตํต ์ปดํฌ๋ํธ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์กฐ๋ฅผ ๋๋์์ต๋๋ค.
components/
โโโ common/
โ |__CheckBox.jsx
โโโ LoginForm.jsx
โโโ SignUpForm.jsx