[Oil of Yats] 옵션 체크박스 구현하기

front-end developer·2022년 11월 3일
0

체크박스 선택이 안되는 문제

input 태그들을 map함수를 통해 화면에 출력했는데, 체크박스 input이 선택이 안되는 오류가 있었다.

체크값을 주기 위해 checkbox input 태그에 checked라는 속성을 추가했고 값으로는 state값을 부여했다. 이 값은 여러 checkbox들 중에서 각 checkbox의 컴포넌트단에서 부여했으므로 독립적으로 작동한다. 또한, 체크가 되면 state값을 변경하여 checked속성이 변하게 구현하였다.

const Checkbox = ({ theme, input, handleCheckbox }) => {
  const [isChecked, setIsChecked] = useState(false);
  const toggleCheck = () => {
    setIsChecked(!isChecked);
  };

  return (
    <label key={Math.random()} id={theme.id}>
      <input
        type="checkbox"
        id={theme.id}
        value={theme.type}
        name={input.name}
        checked={isChecked}
        onChange={e => {
          toggleCheck();
          handleCheckbox(e);
        }}
      />
      {theme.type}
    </label>
  );
};

체크박스 input 정보 저장 시, 체크해제하면 배열에서 삭제하기

현재 체크박스 input에 onChange함수를 걸어 체크하면 값이 배열에 추가되게끔 로직을 구현했다. 그런데 여러 값들을 추가가가능했지만 체크해제를 했을때 값이 삭제되는 구현은 안되고 있었다.

체크박스의 onChange에 부여된 함수 handleCheckbox를 수정했다. 체크가 되면 먼저 체크박스가 스테이 정보 입력란 룸정보 입력란인지 먼저 확인한다. 그러고나서 해당 체크박스 값이 배열에 있는지를 확인하고 없다면 추가, 있다면 삭제하는 로직을 구현했다.

이때, 삭제하는 로직은 해당 배열에 filter 함수를 적용한다. filter함수는 체크된 값과 배열의 값들과 비교해서 일치하지 않는 값만 리턴하고, 그 값을 새로운 배열의 값으로 선언해준다.

const handleCheckbox = e => {
    const { name, value } = e.target;
    const isInfoOfStay = Object.keys(stayInfo).includes(name);

    if (isInfoOfStay) {
      addOrDeleteCheckValue(stayInfo, name, value);
    } else {
      addOrDeleteCheckValue(roomInfo, name, value);
    }
  };

위 함수는 체크박스 input onChange 속성에 부여된 함수다. isInfoOfStay 를 통해 stayInfo인지 roomInfo 인지 확인 한 후, addOrDeleteCheckValue 함수를 실행한다.

const addOrDeleteCheckValue = (targetInfo, inputName, checkedValue) => {
    const isExisted = targetInfo[inputName].includes(checkedValue);

    isExisted
      ? deleteCheckValue(targetInfo, inputName, checkedValue)
      : targetInfo[inputName].push(checkedValue);
  };

addOrDeleteCheckValue 는 인자 targetInfo, inputName, checkedValue 를 받는다.

  • targetInfo : 추가 혹은 삭제하고 싶은 체크박스가 stayInfo의 체크박스인지, roomInfo의 체크박스인지
  • inputName : 스테이 혹은 룸 입력란 중 해당 체크박스 input 태그의 name 속성을 나타낸다. (ex. stay 정보 입력란에서 테마, room 입력란에서 amenity)
  • checkedValue : 체크된 값을 나타낸다. (ex. amenity 중 빅테이블 이라는 값)

isExisted 를 통해 체크된 값이 이미 배열에 추가됐는지 확인한다.

체크가 되어 있지 않다면 push() 메소드를 통해 추가하고

체크가 되어 있다면 deleteCheckValue 함수를 발동시킨다.

const deleteCheckValue = (targetInfo, inputName, checkedValue) => {
    const newValues = targetInfo[inputName].filter(ele => {
      return ele !== checkedValue;
    });

    targetInfo[inputName] = newValues;
  };

deleteCheckValue 함수도 마찬가지로 똑같은 인자 3개를 받는다.

newValues는 배열에 filter()메소드를 적용하여, 체크된 값과 같은 값만 제외한 나머지 값들이 출력되고 그 값들로 이뤄진 배열이다.

newValues 을 기존 targetInfo[inputName] 배열에 대체시킨다. 결과적으로 선택된 값만 지울 수 있게 된다.

stay정보 입력란의 체크박스는 정상작동, room 정보 입력란의 체크박스는 오작동

로직을 구현한 후, console.log 를 통해 값들이 정상적으로 추가 삭제되는지 확인했다. stay의 정보 입력란에서의 체크박스는 정상적으로 추가, 삭제가 되고 있었는데 room 정보 입력란의 체크박스는 값이 이상했다.

room 정보는 룸추가 버튼을 누르면 나오는 모달창에서 정보를 작성하며, 작성이 끝나고 제출하면 모달창이 사라지고 room UI가 생성된다. 그리고 또 룸추가버튼을 눌러 추가적으로 룸에 대한 정보를 작성할 수 있다.

첫번째 룸을 작성할 때는 정보가 올바르게 입력되었으나, 두번째 룸부터 값이 이상했다. 그래서 첫번째 룸 작성이 완료되고 그 값이 초기화가 안됐다는 의심을 해봤고, 결과적으로 그 원인이 맞았다.

따라서 모달창을 handle하는(키고, 닫는) 함수에 룸정보를 초기화하는 함수를 추가해줬다.

const initializeRoomInfo = () => {
    setRoomInfo({
      room_name: '',
      bed: '',
      min_capacity: '',
      max_capacity: '',
      checkin: '',
      checkout: '',
      area: '',
      week_price: '',
      weekend_price: '',
      peek_price: '',
      room_type: '',
      feature: [],
      amenity: [],
      add_on: [],
      room_images: '',
    });
  };

const handleModal = () => {
    initializeRoomInfo();
    setIsOpen(!isOpen);
  };
profile
학습한 지식을 개인적으로 정리하기 위해 만든 블로그입니다 :)

0개의 댓글