[React] checkbox 쉽게 다루기 (allCheck)

🍉effy·2022년 9월 30일
0
post-custom-banner

(멋있는 짤이다 !!)

checkbox 가 4개일 때... 그리고 checkbox 가 50개일 때
같은 방법으로 쓸 순 없다 .,,,!

checkbox 전체 선택 코드 개선해보기 !


input이 폭포처럼 쏟아지는 프로젝트를 맡다보니...
더 효율성 있는 방법을 찾아보고...알아보고 한 끝에 너무 간단한 방법 발견했다


  const [checked, setChecked] = useState<boolean[]>([
    false,
    false,
    false,
    false,
  ]);
  
  const handleChangeAll = (event: ChangeEvent<HTMLInputElement>) => {
    setChecked([
      event.target.checked,
      event.target.checked,
      event.target.checked,
      event.target.checked,
    ]);
  };

  const handleChangeProvision = (event: ChangeEvent<HTMLInputElement>) => {
    setChecked([event.target.checked, checked[1], checked[2], checked[3]]);
  };

  const handleChangePrivacy = (event: ChangeEvent<HTMLInputElement>) => {
    setChecked([checked[0], event.target.checked, checked[2], checked[3]]);
  };

  const handleChangeUnique = (event: ChangeEvent<HTMLInputElement>) => {
    setChecked([checked[0], checked[1], event.target.checked, checked[3]]);
  };

  const handleChangePromotion = (event: ChangeEvent<HTMLInputElement>) => {
    setChecked([checked[0], checked[1], checked[2], event.target.checked]);
  };

  const isDisabled = !(
    checked[0] === true &&
    checked[1] === true &&
    checked[2] === true
  );

흠 .. 정말 길다.
겨우 네개의 체크박스를 전체 선택, 개별 선택하는 것 뿐인데 좀 하드하다.

그런데 만약 체크박스가 네개가 아니라 50개라면 이를 다 이렇게 할 건 아니잖아요.
checkbox 가 50개씩, 10개의 폼을 만든다고 가정할 때,
재사용할 수 있도록 컴포넌트화해서 사용해보자.


const [serviceScope, setServiceScope] = useState<string[]>([]);
const [diseases, setDiseases] = useState<string[]>([]);
  
const handleChangeServiceScope = (e: React.ChangeEvent<HTMLInputElement>) => {
    const isChecked = e.target.checked;
    const value = e.target?.value;

    if (isChecked) {
      setServiceScope([...serviceScope, value]);
    } else {
      setServiceScope(serviceScope.filter((x: string) => x !== value));
    }
  };

  
  
const handleServiceScopeAllCheck = (checked: boolean) => {
    if (checked) {
      const newArr: string[] = [];
      ServiceScope.forEach((el) => newArr.push(el.name));
      setIndustries(numArray);
    } else {
      setIndustries([]);
    }
};
  

만약 두개의 checkbox 폼이 있다고 가정할 때, 빈 배열의 state 안에 개별 선택한 값이나 전체 선택한 값이 들어가게 한다.

handleChangeServiceScope() 함수를 만들어, checkbox 의 onChange 이벤트를 걸고 해당 값을 toggle 시 배열 안에 넣거나 뺀다.


handleServiceScopeAllCheck() 함수는 전체선택 체크박스가 체크될 시, 50개의 value 를 빈 배열안에 모두 넣게 함
    <Stack direction="row" alignItems="center" mb={5}>
      <Checkbox
        onChange={(e) => handleServiceScopeAllCheck(e.target.checked)}
        checked={serviceScope.length === ServiceScope.length}
        }
      />
      <Typography fontSize="1.5rem" color="text.secondary">
        전체선택
      </Typography>
    </Stack>
      
    .
    .
    .
      
    <Checkbox
            key={item.num}
            value={item.name}
            checked={serviceScope.includes(String(item.name))}
            onChange={(e: React.ChangeEvent<HTMLInputElement>,) => handleChangeServiceScope(e)} />

전체 선택 체크박스를 누르면 map 으로 돌린 checkbox 가 모두 check 표시 된다.
serviceScope 배열에 해당 체크박스의 값이 들어있는지의 여부를 판단해서 체크 표시


근데 위에도 적었듯이, 나는 수십개의 체크박스가 있는 폼을 nn개 만들었다. 그래서 컴포넌트로 만들어서 쉽게 갖다쓰면 끝 ~!


export function AllCheckBox({ handleChange, arr, state }: Props) {
  return (
    <Stack direction="row" alignItems="center" mb={5}>
      <Checkbox
        onChange={(e) => handleChange(e.target.checked)}
        checked={state.length === arr.length}
        icon={
          <img src={sCheckBoxOff} alt="checkOff" style={{ width: '18px' }} />
        }
        checkedIcon={
          <img src={sCheckBoxOn} alt="checkOn" style={{ width: '18px' }} />
        }
      />
      <Typography fontSize="1.5rem" color="text.secondary">
        전체선택
      </Typography>
    </Stack>
  );

이렇게 컴포넌트를 만들어서,
전체선택 체크박스를 사용하고자 하는 곳에 <AllCheckBox /> 를 갖다 쓰면 된다.

handleChange props 로 위의 전체선택 함수를, arr props 로는 50개의 데이터가 담겨있는 배열을, state props 로는 빈 배열의 state 를 전달해주면 끝!!!

아주 간단합니다


profile
Je vais l'essayer
post-custom-banner

0개의 댓글