checkbox 공통컴포넌트 만들기(1)

sang hyeok Lee·2022년 10월 18일
0

button 컴포넌트에 이어서 checkbox 컴포넌트도 만들어야 했다!
그래서 처음에는 input태그에 checkbox 타입을 주어서 커스텀을 시도하였다!!
하지만 결과는 실패.......

구글링도 해보구 했지만 계속 실패하였다.....
그래서 그냥 내가 직접 만들어 보기로 했다!!

import { useEffect, useState } from 'react';
import * as s from './checkbox.style';
import { ICheckBoxComponent } from './checkbox.type';

export default function CheckboxComponent(props: ICheckBoxComponent) {
  const {
    label,
    setValue,
    setValueArray,
    overlap,
    style,
    valueArray,
    checkboxStyle,
    labelStyle,
    index,
    indexNm,
    setIndexNm,
  } = props;
  const [check, setCheck] = useState(false);

  useEffect(() => {
    if (index && indexNm && index === indexNm) {
      setCheck(true);
    } else {
      setCheck(false);
    }
  }, [index, indexNm]);

  const onClickCheckOverlapTrue = (value: string) => () => {
    if (overlap && !check && setValueArray && !valueArray?.includes(value)) {
      setValueArray((prev) => [...prev, value]);
    }
    if (overlap && check && setValueArray && valueArray?.includes(value)) {
      const newArry = valueArray.filter((el: string) => el !== value);
      setValueArray(newArry);
    }
    setCheck(!check);
  };

  const onClickCheckOverLapFalse = (value: string, indexValue: number) => () => {
    if (setIndexNm) setIndexNm(indexValue);
    if (!overlap && setValue) {
      setValue(value);
    }
  };

  return (
    <s.Wrapper style={style || {}}>
      <s.Checkbox
        style={checkboxStyle || {}}
        check={check}
        onClick={!overlap && index ? onClickCheckOverLapFalse(label, index) : onClickCheckOverlapTrue(label)}
      />
      <s.Label style={labelStyle || {}}>{label}</s.Label>
    </s.Wrapper>
  );
}

내가 만든 checkbox 코드이다.
코드를 보면서 내가 고려했던 부분과 왜 로직을 이렇게 구성했는지 설명하겠다!

checkbox 컴포넌트는 쉽지는 않았다! 고려해 주어야 하는 부분들이 많았다!

먼저, 고려하는 부분은 label부분이었다!

바로 checkbox 옆에 저 문구를 넣어 주어야 하는 것이다!
그래서 props를 통해서 label 를 checkbox 옆에 넣어주어서 사용자가 무엇을 체크했는지 알 수 있게하였다!

그 다음으로 고려를 했던 부분은 중복 가능과 불가능부분이었다!
props에 overlap을 통해서 가능과 불가능을 판단하도록 하였다!

그리고 중요한 부분 중 하나였던 값을 얻는 방법이었다!!
사용자가 체크를 했을 때 그 체크한 값을 가져와야 체크박스를 사용하는 의미가 있다고 생각했다.

그런데 여기서 한 가지 더 고민해햐 하는 부분이 생겼다!
바로 중복일때와 중복이 되지 않을 때 값을 받아는 방법이었다!
중복이 되지 않을 때는 하나만 가져오면 되지만 중복이 가능한 경우 모든 값을 받올 수 있어야 하기 때문이다!

먼저, 중복이 불가는한 경우 상위 컴포넌트에서 useState를 통해서 상태값을 하나 만들어준다! 그리고 그 상태값의 setState함수를 넘겨주고 중복이 불가능할 경우를 구분하여 중복이 아닐 때 함수를 실행시켜서 props로 넘겨준 setState함수를 통해서 사용자가 선택한 값을 가져올 수 있도록 하였다!

중복이 가능한 경우는 먼저 상태값을 배열로 만들었다! 그리고 마찬가지로 setState함수를 넘겨주고 선택한 값들을 배열에 담아서 가져올 수 있도록 하였다! 여기서 한가지 더 고려를 해야하는 점은 바로 다시 checkbox를 눌렀을 때 취소가 된다는 점이다! 그래서 checkbox 컴포넌트 내부에서 check라는 불린타입의 상태 값을 만들어주고 checkbox를 클릭을 했을 때 상태 값을 변하게 해주어서 false일때는 check가 안 되었을 때 true일 때는 check가 되었을 때로 판단을 하였다! 근데 여기서 중요한 것은 클릭을 했을 때 함수가 실행되는데 상태 값은 함수가 끝나야 실행이 되는 것이다! 그래서 check가 false일 때 배열에 담아는 로직을 구성하고 true일 때 배열에서 제거하는 로직을 구성하였다!

 const onClickCheckOverlapTrue = (value: string) => () => {
    if (overlap && !check && setValueArray && !valueArray?.includes(value)) {
      setValueArray((prev) => [...prev, value]);
    }
    if (overlap && check && setValueArray && valueArray?.includes(value)) {
      const newArry = valueArray.filter((el: string) => el !== value);
      setValueArray(newArry);
    }
    setCheck(!check);
  };

위 코드가 중복이 가능할 때 배열에 담아주는 코드이다!

profile
개발자 되기

0개의 댓글