전체선택 컴포넌트

miin·2024년 5월 8일
0

Skill Collection [Function]

목록 보기
46/46

내용

  • 한 테이블 구성으로는 큰 타이틀, 작은 타이틀과 데이터(a), 작은 타이틀과 데이터(b), 작은 타이틀과 데이터(c)
  • 한 페이지에 테이블 두개가 들어감
  • a , b, c각각 api연결을 따로 해줘야 함
  • 해당 컴포넌트를 큰타이틀이 다른 컴포넌트로 다수로 사용됨

기능

  1. 개별 체크박스 선택/해제 기능
  2. 전체 선택을 클릭 시 전체 선택/해제 변경 기능
  3. 전체 선택 시에 하나라도 체크가 해제되면 전체 선택 박스 체크 해제

순서

  1. 각각의 길이만큼 map 돌리기
  2. map 안에서 handleCheck 호출 => 체크on
  3. allCheckList에 title, id를 넣음 => 체크리스트에 push

코드

  • 개별선택
type HandleCheckProps = {
  title:string;
  seq:number;
  id:string;
  isChecked:number;
  setCheckList:React.Dispatch<SetStateAction<CheckList[]>>;
  amount?: number;
}
  
const handleCheck = ({
  title, //해당 테이블의 제목
  isChecked, //체크박스의 체크여부
  setCheckList, //체크박스리스트를 set하는 함수 
  id, //해당 체크박스의 id
  seq,//해당 체크박스의 seq
  amount //해당 체크박스의 amount(optional)
}:HandleCheckProps) => {
  isChecked 
  ? amount 
  	? setCheckList(prev => [...prev, {title, seq, id, amount}])
    : setCheckList(prev => [...prev, {title, seq, id}])
  : setCheckList(prev => prev.filter(e => e.id !== id && e.title === title)
  • 전체선택
const [aCheckList, setACheckList] = useState([])
const [bCheckList, setBCheckList] = useState([])
const [cCheckList, setCCheckList] = useState([])

const handleAllCheck = (checked:boolean) => {
  if(checked) {
    setIsAllChecked(true) //전체선택 외에도 전체선택 체크박스가 있음
    
    a.map(item => {
      handleCheck({ //개별체크하는 함수를 같이 사용
        title,
        isChecked: checked ? 1 : 0,
        setCheckList: setACheckList,
		id: item.id,
        seq: item.seq,
   		amount: item.amount
          })
      
      setAllCheckList(prev => [...prev, {title, id:item.id}])
    });
    //b,c 모두 같은 코드
    
    //전체선택중 하나라도 체크 해제되면 전체선택 풀림
 useEffect(() => {
   if(aCheckList.length + bCheckList.length + cCheckList.length
      === allCheckList.length){
     setIsAllChecked(false)
     return
   }
   setIsAllChecked(false)
 },[allCheckList, aCheckList,bCheckList, cCheckList])
    
  • return
<Checkbox
onChange={()=>{
  setAllCheck(!allCheck)
  handleAllCheck(!allCheck)
}/>
checked={isAllChecked && allCheckList[0].titl === title}
<button
onChange={()=>{
  setAllCheck(!allCheck)
  handleAllCheck(!allCheck)
}>All Check</button>

발생한 이슈

  1. 해당 루트에서 배열의 길이만큼 체크리스트에 push가 되어야하는데 하나만 체크가 되었다

    이유: react 비동기의 문제였음

    이전코드 => setCheckList([...checkList, {seq, id}]
    해결코드 => setCheckList(prev => [...pprev,{seq,id}])

  2. (한 페이지에 테이블 두개 들어감) 테이블1 전체선택을 체크하고 해제하면 테이블2의 체크박스들도 영향을 받았음

    이유: 한페이지에 하나의 체크리스트만 만들어서

    해결 => 각 테이블당 리스트상태 만들기

    - a, b, c list & allCheckList 들을 모두 다 따로만들기
    - 버튼핸들러만 부모에 넣고
    - 나머지는 전부 자식(공통컴포넌트)에 넣었음 사용할 데이터만 넘겨주면 모두 사용할 수 있게... 근데 자식에 전부 넣어도 되는건지 모르겠음

0개의 댓글