[TIL] MUI Check box

이현동·2023년 7월 26일
1

TIL

목록 보기
59/59
post-custom-banner

mui check box 사용법

보통 <CheckBox /><FormControlLabel /> 컴포넌트에서 control 속성에 정의하여 사용합니다.

checked

checked 속성이 true면 체크로 표시되고, false면 체크가 해제됩니다.

...
/** 상품 선택 handler
 * 해당 상품의 인덱스, event, 해당 목록 state, 해당 목록 useState를 받음
 */
const handleCheckedChange = (index, event, checkedLists, setCheckedLists) => {
        const itemRef = [...checkedLists];
        itemRef[index] = event.target.checked;
        setCheckedLists([...itemRef]);
    };
...
<FormControlLabel
	control={
	    <Checkbox
	        checked={isCheckedNoTaxPrducts[index]}
	        onChange={event =>
	            handleCheckedChange(
	                index,
	                event,
	                isCheckedNoTaxPrducts,
	                setIsCheckedNoTaxProducts,
	            )
	        }
	    />
	}
	sx={{ pl: "2px", mr: 0 }}
/>
...
  • onChange를 통해서 클릭 시 event.target.checked가 true, false로 값을 바꿔준다.
  • 처음 리스트의 길이 만큼의 빈 배열에 모두 false로 채운 후 map을 통해 뿌려진<FormControlLabel />의 특정 checked의 값을 true로 바꿔주기 위해 index값을 이용했다.

indeterminate

indeerminate 속성을 통해서 전체 선택 기능을 추가했습니다.

...

/** 상품 전체 선택 handler
 * 해당 상품의 event, 해당 목록 state, 해당 목록 useState를 받음
 */
const handleCheckedChangeAll = (event, checkedLists, setCheckedLists) => {
    const itemRef = [...checkedLists];
    itemRef.forEach((_item, index) => (itemRef[index] = event.target.checked));

    setCheckedLists([...itemRef]);
};

/** 상품 checked 확인 handelr
 * 상품 목록 state를 받음
 */
const handleIndeterminate = array => {
    if (array.every(item => item === false)) {
        return false;
    } else if (array.every(item => item === true)) {
        return false;
    } else {
        return true;
    }
};

...
<FormControlLabel
    control={
        <Checkbox
            checked={isCheckedNoTaxPrducts.every(
                item => item === true,
            )}
            indeterminate={handleIndeterminate(
                isCheckedNoTaxPrducts,
            )}
            onChange={event => {
                handleCheckedChangeAll(
                    event,
                    isCheckedNoTaxPrducts,
                    setIsCheckedNoTaxProducts,
                );
            }}
        />
    }
    sx={{ mr: 0 }}
/>
  • 전체를 check해주는 을 눌렀을 때 handleCheckedChangeAll을 실행해서 배열의 모든 값을 true로 바꿔주거나 false로 바꿔줍니다.
  • checked 속성은 모든 배열이 true일 때에만 true를 반환해서 checked가 될 수 있도록 했습니다.
  • indeterminate는 handleIndeterminate에서 배열이 모두 true이거나 모두 false면 리턴 false, 이 외에는 true를 반환해서 아래와 같이 (-)가 나오도록 했습니다. (더 좋은 조건문이 없을까,, 고민해봤는데 우선 저렇게 함수로 만들어서 했습니다..!)

이전 코드

useEffect(() => {
        if (checkedNoTaxCancel.every(item => item === true)) {
            setNoTaxSelectAll(true);
        } else {
            setNoTaxSelectAll(false);
        }
    }, [checkedNoTaxCancel]);

useEffect(() => {
	if (checkedHasTaxCancel.every(item => item === true)) {
		setHasTaxSelectAll(true);
	} else {
		setHasTaxSelectAll(false);
	}
}, [checkedHasTaxCancel]);
  • interminate 속성을 모를 때에는 위처럼 전체 선택을 하게 해주는 체크박스를 useState에 저장하고 useEffect를 사용해서 값이 변화할 때마다 checked를 업데이트 해주었습니다..
  • 또한 리렌더링 될 때 useEffect도 실행, setState의 값이 변경될 때 또 useEffect가 실행되므로 렌더링이 두번 발생하게 됩니다.
  • <CheckBox />를 handleChange 할 때, 조건을 계산해서 처리하는 것이 바른 방법이고, state가 변할 때마다 수행하는 것은 깜박임이 문제될 수 있다고 합니다.
profile
https://hdlee.dev
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 8월 7일

GOOD

1개의 답글