Frontend/TypeScript

[ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ(TypeScript) ] 2๊ฐœ ์ด์ƒ์˜ ๋™์ผํ•œ ๊ธฐ๋Šฅ์ธ useState์™€ handleChange๋ฅผ ๊ฐ๊ฐ ํ•˜๋‚˜๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

YWTechIT 2022. 5. 16. 22:02
728x90

๐Ÿ“ 2๊ฐœ ์ด์ƒ์˜ ๋™์ผํ•œ ๊ธฐ๋Šฅ์ธ useState์™€ handleChange๋ฅผ ๊ฐ๊ฐ ํ•˜๋‚˜๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

๊ตฌ๋…์‹ ์ฒญ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ๊ฐœ์ธ์ •๋ณด์ˆ˜์ง‘ checkbox์™€ ๊ด‘๊ณ ์„ฑ ์ •๋ณด ์ˆ˜์‹  input checkbox๋ฅผ useState๋กœ ๊ด€๋ฆฌํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ, ์—ฌ๋Ÿฌ ๊ฐœ์˜ useState๋กœ ์„ ์–ธํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋‹ˆ๊นŒ ์ฝ”๋“œ๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๊ธธ์–ด์ ธ ์ข‹์€ ์ฝ”๋“œ๋ผ๊ณ  ๋ณด๊ธฐ ํž˜๋“ค์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ธฐ์กด์— const [state, setState] = useState(false)์ฒ˜๋Ÿผ ์„ ์–ธํ–ˆ๋‹ค๋ฉด ์ด๋ฅผ object๋กœ ๋ฌถ์–ด ์„ ์–ธํ•˜๋‹ˆ ์ฝ”๋“œ๊ฐ€ ์ค„์–ด๋“ค์—ˆ๋‹ค.

import { useState } from "react";

// ๋ฆฌํŒฉํ† ๋ง ์ „
export default function Subscription() {
  const [allAgree, setAllAgree] = useState<boolean>(false);
  const [privateAgree, setPrivateAgree] = useState<boolean>(false);
  const [adAgree, setAdAgree] = useState<boolean>(false);
}


// ๋ฆฌํŒฉํ† ๋ง ํ›„
interface AgreeType {
  personalInfo: boolean;
  adInfo: boolean;
}

export default function Subscription() {
  const [{ personalInfo, adInfo }, setAgree] = useState<AgreeType>({
    personalInfo: false,
    adInfo: false,
  });
}

๋˜ํ•œ, checkbox์˜ state๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด setAgree์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋Š”๋ฐ, ๋ฆฌํŒฉํ„ฐ๋ง ์ „์—๋Š” allAgree๋งŒ์„ ์œ„ํ•œ allHandleChange๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ , ๋‚˜๋จธ์ง€ privateAgree, adAgree๋ฅผ ์œ„ํ•œ handleChange ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ, ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ณ€์ˆ˜๋ช…๋งŒ ๋‹ค๋ฅผ ๋ฟ ๋™์ผํ•œ ์—ญํ• ์„ ํ•˜๋Š”๋ฐ๋„ ํ•จ์ˆ˜๋ฅผ 2๊ฐœ ์ด์ƒ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋…์„ฑ์ด ๋งค์šฐ ์ข‹์ง€ ์•Š์•˜๊ณ  ์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด  ํ•จ์ˆ˜ 1๊ฐœ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด input์˜ id๊ฐ’์œผ๋กœ ์กฐ๊ฑด์„ ๊ตฌ๋ถ„ํ•˜์—ฌ check๋ฅผ toggle ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ค์ •ํ–ˆ๋‹ค.

728x90

๊ทธ๋ฆฌ๊ณ  ์ „์ฒด ๋™์˜ํ•ฉ๋‹ˆ๋‹ค ๊ธฐ๋Šฅ์€ ํ•ด๋‹น input์˜ checked property์— personalInfo, adInfo๊ฐ€ ์ฐธ์ผ ๋•Œ๋งŒ checked๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ฒŒ ์„ค์ •ํ–ˆ๋‹ค. ์ด๋•Œ ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ๋ชจ๋‘ ๋™์˜ ํ–ˆ์„ ๋•Œ์˜ ์กฐ๊ฑด์„ const checkedAllInfo = personalInfo && adInfo ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ–ˆ๋‹ค. ์—ฌ๋‹ด์œผ๋กœ ํ•˜๋‹จ ์ฝ”๋“œ๋ธ”๋Ÿญ์˜ 92๋ฒˆ ๋ผ์ธ์„ else๋กœ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ์ง€ ์•Š๋Š”๊ฐ€๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, 67๋ฒˆ ๋ผ์ธ์— AgreeTypeํƒ€์ž…์„ ์ •์˜ํ•ด๋†“์•˜๊ธฐ ๋•Œ๋ฌธ์— else ์กฐ๊ฑด์— personalInfo ํ˜น์€ adInfo ์™ธ์— ๋‹ค๋ฅธ id๊ฐ€ ์˜จ๋‹ค๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ ์ œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†๋‹ค. ๋งŒ์•ฝ, else๋ฅผ ๋„ฃ๊ณ  ์‹ถ๋‹ค๋ฉด 7๋ฒˆ๋ผ์ธ์— AgreeType์— [key: string]: boolean์„ ๋„ฃ์–ด ๋‹ค๋ฅธ id๊ฐ€ ์˜ค๋”๋ผ๋„ ๊ทธ id๊ฐ€ boolean ํƒ€์ž…์ด๋ผ๊ณ  ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค.

import { useState } from "react";

// ๋ฆฌํŒฉํ† ๋ง ์ „
export default function Subscription() {
  const [allAgree, setAllAgree] = useState<boolean>(false);
  const [privateAgree, setPrivateAgree] = useState<boolean>(false);
  const [adAgree, setAdAgree] = useState<boolean>(false);

  const allHandleChange = () => {
    if (allAgree) {
      setAllAgree(false);
      setPrivateAgree(false);
      setAdAgree(false);
    } else {
      setAllAgree(true);
      setPrivateAgree(true);
      setAdAgree(true);
    }
  };

  const handleChange = (
    setState: React.Dispatch<React.SetStateAction<boolean>>
  ) => {
    setState((state) => !state);
  };

  return (
    <>
      <Section centered margin={{ top: 60 }}>
        <label htmlFor="agree-all">
          <input
            id="agree-all"
            type="checkbox"
            checked={allAgree}
            onChange={allHandleChange}
          />
          ์ „์ฒด ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.
        </label>

        <label htmlFor="agree-private">
          <input
            id="agree-private"
            type="checkbox"
            checked={privateAgree}
            onChange={() => handleChange(setPrivateAgree)}
          />
          ๊ฐœ์ธ์ •๋ณด ์ˆ˜์ง‘ ๋ฐ ์ด์šฉ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. (ํ•„์ˆ˜)
        </label>

        <label htmlFor="agree-advertise">
          <input
            id="agree-advertise"
            type="checkbox"
            checked={adAgree}
            onChange={() => handleChange(setAdAgree)}
          />
          ๊ด‘๊ณ ์„ฑ ์ •๋ณด ์ˆ˜์‹ ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. (ํ•„์ˆ˜)
        </label>

        <Button disabled={!(privateAgree && adAgree)}>๊ตฌ๋…ํ•˜๊ธฐ</Button>
      </Section>
    </>
  );
}

// ๋ฆฌํŒฉํ† ๋ง ํ›„ 

// #1
interface AgreeType {
  [key: string]: boolean
}

// #2
interface AgreeType {
  personalInfo: boolean;
  adInfo: boolean;
}

export default function Subscription() {
  const [{ personalInfo, adInfo }, setAgree] = useState<AgreeType>({
    personalInfo: false,
    adInfo: false,
  });
  const checkedAllInfo = personalInfo && adInfo;

  const handleCheck = (e: { target: HTMLInputElement }) => {
    const { id, checked } = e.target

    if (id === 'all') {
      setAgree(
        checked
          ? {
              personalInfo: true,
              adInfo: true,
            }
          : {
              personalInfo: false,
              adInfo: false,
            },
      )
    } else {
      setAgree((prevState) => ({
        ...prevState,
        [id]: !prevState[id],
      }))
    }
  }

  return (
    <>
      <Section centered margin={{ top: 60 }}>
        <label htmlFor="all">
          <input
            id="all"
            type="checkbox"
            checked={personalInfo && adInfo}
            onChange={handleChange}
          />
          <Text size={17} bold>
            ์ „์ฒด ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.
          </Text>
        </label>

        <label htmlFor="personalInfo">
          <input
            id="personalInfo"
            type="checkbox"
            checked={personalInfo}
            onChange={handleChange}
          />
          <Text size="medium">๊ฐœ์ธ์ •๋ณด ์ˆ˜์ง‘ ๋ฐ ์ด์šฉ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. (ํ•„์ˆ˜)</Text>
        </label>

        <label htmlFor="adInfo">
          <input
            id="adInfo"
            type="checkbox"
            checked={adInfo}
            onChange={handleChange}
          />
          <Text size="medium">๊ด‘๊ณ ์„ฑ ์ •๋ณด ์ˆ˜์‹ ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. (ํ•„์ˆ˜)</Text>
        </label>

        <Button disabled={!checkedAllInfo}>๊ตฌ๋…ํ•˜๊ธฐ</Button>
      </Section>
    </>
  );
}
๋ฐ˜์‘ํ˜•