24. 08. 14 TIL

우리여기까진좋앗잖아...

 

하지만 폼을 수정해야 했다...

 

체크박스 아이콘을 따로 사용해야 했기 때문,..

 

그 체크박스 컴포넌트는 원래

 

onChange 하나만 받고

체크 박스의 체크 상태를 관리하는 useState와 hover가 되었는지 여부를 관리하는 useState 2개만 있었다

 

그래서 사용자가 체크박스를 클릭하면 함수가 호출되어

현재 체크 상태를 반전시키고 새로운 상태를 onChange 함수를 통해 부모 컴포넌트에 전달했다

더보기
더보기

부모 컴포넌트는 자식 컴포넌트에게 프롭스를 통해 데이터 전달,

자식 컴포넌트는 부모 컴포넌트에게 데이터를 전달하기 위해 부모 컴포넌트로부터 받은 함수를 호출하면

데이터가 부모 컴포넌트로 전달됨

이제 코드 수정...

 

일단 기존 코드와 비교해보자면

const handleSelectAll = (checked: boolean) => {
  setValue('age14', checked);
  setValue('terms', checked);
  setValue('privacy', checked);
};

 

 

기존에는 checked라는 인자를 받는다

이 인자는 체크박스의 체크되었는지, 해제되었는지의 상태를 나타낸다

ㅇ ㅣ인자는 체크박스의 체크 상태를 나타낸다

 

const handleSelectAll = () => {
  const newCheckedState = !allSelected;
  setValue('age14', newCheckedState);
  setValue('terms', newCheckedState);
  setValue('privacy', newCheckedState);
};

새 코드는 인자를 받지 않고

함수 내부에서 새로운 체크 상태를 결정한다

newCheckedState는 allSelected의 반대값을 가지는데

모든 항목이 선택된 상태면 이를 해제하고, 해제된 상태면 선택한다

즉, 반전시키는 역할이다

 

 

그리고 기존엔 

setValue('age14', checked);
setValue('terms', checked);
setValue('privacy', checked);

checked 인자를 사용해 모든 체크박스의 상태를 업데이트 했지만

 

setValue('age14', newCheckedState);
setValue('terms', newCheckedState);
setValue('privacy', newCheckedState);

새 코드는 계산된 newCheckedState 값을 사용해 모든 체크박스의 상태를 업데이트 한다

setValue는 폼의 특정 필드 값을 업데이트 하는 데 사용하고

첫번 째 인자는 필드의 이름, 두 번째 인자는 설정할 값이다

그러니까 newCheckedState가 true면 그 필드는 true가 된다

 

 

원래는 다른 코드였지만

그렇게 하면 전체 동의를 눌렀을 때 바로 회원가입이 되어버리는 문제가 생겨서

지피티를 굴리고 굴려서 저렇게 답을 찾아냈다

 

사실 이 부분에 문제가 있던 건 아니고

 

체크박스를 사용했을 때 부분이었는데

전체 동의만 체크박스 타입을 사용했다

 

<CheckBox
  useInputElement={true}
  checked={allSelected}
  onChange={handleSelectAll}
/>

 

사용자가 전체 동의 체크박스를 클릭하면

handleSelectAll 함수가 호출되고,

이 함수는 모든 체크박스의 상태를 반전시킨다.

 

그리고 다른 체크 박스들은

<CheckBox
  checked={terms}
  onChange={(checked) => setValue('terms', checked)}
/>

그냥 이렇게 써서 

checked로 체크되었는지 여부를 확인하고 (useWatch로 관찰)

onChange는 사용자가 체크박스의 상태를 변경했을 때 실행되는 함수이므로

사용자가 체크박스를 체크하면 (checked)라는 값이 변경된 상태로 설정되고

그 상태를 setValue 함수로 폼 데이터의 terms 필드에 반영하는 것이다

 

 

아우 헷갈린다 코드 수정을 하도 해서 ㅋㅋ ;; ㅜㅜ

 


하여튼 이제 

<CheckBox
  useInputElement={true}
  checked={allSelected}
  onChange={handleSelectAll}
/>

이 부분이 어떻게 checkbox와 연결되는지 알아봅시다 ^,.^

 

먼저

전체 동의 박스는 다른 박스와 다르다

이유는?... 저거 누르면 가입하기 안 눌러도 회원가입이 됨 자꾸,,,

 

그래서 저 부분만 바꿔주는 거다

 

그럼 저 체크박스 컴포넌트는

  checked?: boolean;
  inputTypeCheckbox?: boolean;
  
   checked = false,
  inputTypeCheckbox = false,

프롭스로 저걸 추가로 받고

(checked -> 체크박스가 체크되어 있는지 여부)

(inputTypeCheckbox -> 이 체크박스가 진짜 input 태그처럼 동작할지 여부)

기본값은 false로 설정해준다

즉, 아무것도 정해지지 않을 때는 체크되지 않거나 진짜 input처럼 동작하지 않게 한다

 

const [isChecked, setIsChecked] = useState(checked);

그리고 체크되었는지 확인하는 스테이트는 checked를 기본값으로 넣어준다

 

또 추가로 

useEffect(() => {
  setIsChecked(checked);
}, [checked]);

useEffect를 넣어서 checked 값이 바뀔때마다 isChecked도 함께 바뀌도록 해준다

즉, 부모 컴포넌트에서 체크 상태를 바꾸면 이 컴포넌트도 체크 상태가 바뀌도록 한다

 

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  const newCheckedStatus = event.target.checked;
  setIsChecked(newCheckedStatus);
  onChange(newCheckedStatus);
};

이건 사용자가 체크박스를 클릭했을 때 실행되는 함수다

체크 상태를 반대로 바꾸고 부모 컴포넌트에 그 결과를 알려준다

 

const handleClick = () => {
  if (!inputTypeCheckbox) {
    const newCheckedStatus = !isChecked;
    setIsChecked(newCheckedStatus);
    onChange(newCheckedStatus);
  }
};

그리고 이 함수는 input 태그처럼 동작하지 않는 체크박스일 때만 동작한다

사용자가 체크박스를 클릭하면 체크 상태를 반대로 바꾸고 그 결과를 부모 컴포넌트에 알린다

 

그리고 이건 inputTypeCheckbox가 true 일 때만

{inputTypeCheckbox && (
  <input
    type='checkbox'
    checked={isChecked}
    onChange={handleInputChange}
    className='absolute left-0 top-0 w-6 h-6 opacity-0 cursor-pointer'
  />
)}

보여주는 건데

input 요소는 안 보이게 만들고 클릭하면 handleInputChange 함수를 실행한다

 


전체 동작 흐름을 정리하자면

<CheckBox
  inputTypeCheckbox={true}
  checked={allSelected}
  onChange={handleSelectAll}
/>

allSelected는 전체 동의가 체크된 상태인지 아닌지를 결정해 

(전체동의 체크박스가 체크된 상태면 true고, 하나라도 체크 안 되면 false) 값을 checked로 전달한다

 

그리고 사용자가 전체 동의 박스를 클릭하면

const handleSelectAll = () => {
  const newCheckedState = !allSelected; // 현재 allSelected 상태를 반전시킵니다.
  setValue('age14', newCheckedState); // age14 상태를 반전된 값으로 설정
  setValue('terms', newCheckedState); // terms 상태를 반전된 값으로 설정
  setValue('privacy', newCheckedState); // privacy 상태를 반전된 값으로 설정
};

onChange 함수가 호출되어 

현재 allSelected 상태를 반전시킨다

 

그럼 상태들이 변경되고, 변경되면 allSelected 값도 다시 계산되어 변경된다

그럼 모든 체크박스의 상태가 최신 상태로 업데이트 된다

 

그리고 체크박스 컴포넌트에서 inputTypebox를 true로 전달하면

{inputTypeCheckbox && (
  <input
    type='checkbox'
    checked={isChecked}
    onChange={handleInputChange}
    className='absolute left-0 top-0 w-6 h-6 opacity-0 cursor-pointer'
  />
)}

이 input이 동작하는데

isChecked가 true면 체크된 상태로 보이고 반대면 체크되지 않은 상태로 보인다

쉽게 말해 이 값에 따라 체크박스가 체크된 상태로 보일지, 안 보일지 여부를 결정한다

 

onChange는 사용자가 이 체크박스를 클릭하여 상태가 변경될 때 실행된다

 

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  const newCheckedStatus = event.target.checked;
  setIsChecked(newCheckedStatus);
  onChange(newCheckedStatus);
};

event.taget.checked는 사용자가 체크박스를 클릭한 후의 상태를 가져온다

true면 체크가 됐고, 반대면 안 된 거고

이 값을 변수에 저장한다

 

그리고 이 값으로 isChecked를 업데이트 한다

그리고 onChange라는 함수를 호출해 체크박스의 새로운 상태를 전달한다

 

 

아뭐래!!!!다시정리합니다

 


먼저 전체 동의 체크박스를 클릭한다

<CheckBox
  inputTypeCheckbox={true}
  checked={allSelected}
  onChange={handleSelectAll}
/>

이 부분이 호출된다

여기서 checked는 이 체크박스가 체크가 된 상태인지 결정하고

onChange는 사용자가 이 전체동의 체크박스를 클릭했을 때 실행될 함수를 지정한다

 

그리고 input 머시기가 true니까

{inputTypeCheckbox && (
  <input
    type='checkbox'
    checked={isChecked}
    onChange={handleInputChange}
    className='absolute left-0 top-0 w-6 h-6 opacity-0 cursor-pointer'
  />
)}

여기가 렌더링 된다

이 input요소는 isChecked에 따라 체크 상태를 결정하고,

isChecked는 allSelected 값에서 초기화된다

그리고 사용자가 이 체크박스를 클릭하면 handleInputChange 함수가 호출된다

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  const newCheckedStatus = event.target.checked;
  setIsChecked(newCheckedStatus);
  onChange(newCheckedStatus);
};

이것이요

사용자가 체크박스를 클릭하면 체크박스의 상태를 가져오고

isChecked 상태를 업데이트 한다

onChange가 호출되며, 여기서 onChange는 handleSelectAll 함수를 말한다

즉, 전체 동의 체크 박스를 클릭하면 handleSelectAll 함수가 실행된다

const handleSelectAll = () => {
  const newCheckedState = !allSelected;
  setValue('age14', newCheckedState);
  setValue('terms', newCheckedState);
  setValue('privacy', newCheckedState);
};

그리고 이 함수를 실행시켜 준다

 

1. 전체 동의 체크 박스 클릭

2. handleInputChange 함수 호출 

3. handleInputChange 함수 내부에서 onChange로 연결된 handleSelectAll 함수가 호출됨

4. handleSelectAll 함수가 실행되어 모든 체크박스 상태 변경

5. 컴포넌트 다시 렌더링

 

 


다른 체크박스는

 

1. 체크박스 렌더링 -> checked={age14} 와 같은 상태를 기반으로 체크박스가 체크된 상태인지 아닌지 결정한다

2. 사용자 클릭 -> 사용자가 체크박스를 클릭하면 handleInputChange 함수가 실행되어 체크 상태가 반전된다

3. 상태 업데이트 -> onChange 함수가 호출되어 age14 상태가 업데이트 된다

4. 다시 렌더링

'TIL' 카테고리의 다른 글

24. 08. 20 TIL  (0) 2024.08.19
24. 08. 16 TIL  (0) 2024.08.16
24. 08. 13 TIL  (0) 2024.08.13
24. 08. 12 TIL  (0) 2024.08.12
24. 08. 09 TIL  (0) 2024.08.09