[๋ฆฌ์•กํŠธ] ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ ๊ตฌํ˜„ (๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ. CheckBox)

2025. 10. 20. 11:28ใ†React

์ด๋ฒˆ ์ž‘์—…์—์„œ๋Š” ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•œ ์—ฌ๋Ÿฌ ๋ฌธ์ œ๋ฅผ ์ •๋ฆฌํ•˜๊ณ , ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ๋ฐ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

 

1. ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ ๊ตฌํ˜„

โœ… ์ฃผ์š” ๊ตฌํ˜„ ๋‚ด์šฉ

  1. ๋น„๋ฐ€๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
    • ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ๊ฐ’์ด ๋น„์–ด ์žˆ์œผ๋ฉด “๊ฐ’์„ ์ž…๋ ฅํ•˜์„ธ์š”” ์—๋Ÿฌ ์ถœ๋ ฅ
    • ์ž…๋ ฅ์ด ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ๋ผ๋ฉด “ํ˜•์‹ ์˜ค๋ฅ˜” ์—๋Ÿฌ ์ถœ๋ ฅ
  2. ์•„์ด๋”” ์ค‘๋ณต ํ™•์ธ
    • “์ค‘๋ณต ํ™•์ธ” ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ, ์„œ๋ฒ„์—์„œ ํ•ด๋‹น ์•„์ด๋””์˜ ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
    • ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด “์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์•„์ด๋””์ž…๋‹ˆ๋‹ค” ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
    • ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด “์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์•„์ด๋””์ž…๋‹ˆ๋‹ค” ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
  3. ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ
    • ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ํ•„๋“œ๋ฅผ ๋‹จ์ผํ™”ํ•˜๊ณ , ๋‚ด๋ถ€์ ์œผ๋กœ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ ํ•„๋“œ ๋ชจ๋‘ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ
  4. ํšŒ์›๊ฐ€์ž… ๊ฒฝ๋กœ๋ณ„ 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