본문 바로가기
Front-end/React

[React] 페이지 별 체크박스 - 전체/개별 체크박스 페이지 이동해도 checked 저장

by 꼬바리 2022. 12. 23.

리액트 체크 박스 검색시 가장 많이 나오는

전체 체크박스 및 개별 체크박스

 

그치만 페이지를 이동하면 전체 체크박스가 새로고침 되기 때문에 다 날라간다

 

나는 state에 페이지별 선택 ID를 남겨주었다

 

 

해당예제는 사용자 아이디 리스트.

 

// user info
const [users , setUsers] = useState([]);        //페이지 내 전체 유저
const [selectableUsers , setSelectableUsers] = useState([]); // 페이지내 선택가능 유저 - 전체 선택 onoff
//체크박스
const [checkItems, setCheckItems] = useState([]);   //페이지 상관없이 체크한 아이템
const [checkItemsPage, setCheckItemsPage] = useState([]);   //페이지 내 체크한 아이템 - 전체 선택 onoff

userList를 받아온다.

selectableUser는 선택가능한 유저리스트 (상태에따라 선택불가능한 경우)

 

const funUserList = () => {
    let params = {
        page : page,
        pageLength: pageLimit,
        ...
    }

    userList(params).then((res)=>{
        if(res.statusCode===10000){
            const result = res.data
            setUsers(result);
            //선택 가능한 유저
            const userable = result.filter(user => user.PARTICIPANT_YN == 'N')
            let ableList = userable.map(i=>i.LOGIN_ID)
            setSelectableUsers(userable)

            //페이지별 체크 리스트 생성
            let temp = [];
            if(checkItems.length > 0){
                temp = checkItems.filter(item=>ableList.includes(item))
            }
            setCheckItemsPage(temp)
        }
    })
}

유저 리스트를 가져오는 함수에서 

setCheckItemsPage 

데이터를 가공하여 만들어준다.

 

페이지를 이동하면 페이지 별 check된 값이 날라가기떄문에

 

 

const handleAllCheck = (checked) => {
    if(checked) {
        // 전체 선택 클릭 시 데이터의 모든 아이템(id)를 담은 배열로 checkItems 상태 업데이트
        const temp = [];
        selectableUsers?.forEach((user) => {
            temp.push(user.LOGIN_ID)
        });
        // 기존 배열 + 추가 배열 합치기
        var merged = checkItems.concat(temp);
        var unique = merged.filter((item, pos) => merged.indexOf(item) === pos);
        setCheckItems(unique);  //전체 선택된
        setCheckItemsPage(temp);    // 페이지별 선택된 리스트
    }else {
        // 전체 선택 해제 시 checkItems 를 빈 배열로 상태 업데이트
        setCheckItems(checkItems.filter(item=>!checkItemsPage.includes(item)));
        setCheckItemsPage([])  
    }
}
const handleCheck = (checked, id) => {
    if (checked) {
        // 단일 선택 시 체크된 아이템을 배열에 추가
        setCheckItems(prev => [...prev, id]);
        setCheckItemsPage(prev => [...prev, id]);
    } else {
        // 단일 선택 해제 시 체크된 아이템을 제외한 배열 (필터)
        setCheckItems(checkItems.filter((item) => item !== id));
        setCheckItemsPage(checkItemsPage.filter((item) => item !== id));
    }
};

설명하기 어렵다.

리액트나 자바스크립트 기본만 아는 사람이여도

코드와 주석 보면 쉽게 알수있다.3

 

<thead>
  <tr>
    <th>
      <div className="chkbox chk-single">
        <input id="all" type="checkbox" className="chk" name='chkAll'
              onChange={(e) => handleAllCheck(e.target.checked)}
              // 데이터 개수와 체크된 아이템의 개수가 다를 경우 선택 해제 (하나라도 해제 시 선택 해제)
              checked={
              users?.length == 0 ? false 
              : checkItemsPage.length === selectableUsers.length ? true : false}
        />
        <label htmlFor="all" style={{padding : 0}}></label>
      </div>
    </th>
    <th>기관</th>
    <th>직책</th>
    <th>ID</th>
    <th>성명</th>
  </tr>
</thead>

전체 체크박스가 있는 테이블 해더 코드

 

<tbody>
    {users?.length > 0 ?
        users?.map((item,index) => {
            return(
                <tr key={index} className='uncursor'>
                    {
                        item.PARTICIPANT_YN === 'Y' ?
                        <td>
                            <div className="chkbox no-click">
                                <input type="checkbox" className="chk"
                                    id={"chk"+item.ID}
                                    name={"chk"+item.ID}
                                    checked={true}
                                    disabled
                                    />
                                <label htmlFor={"chk"+item.ID} style={{padding : 0}}></label>
                            </div>
                        </td>
                        : 
                        <td>
                            <div className="chkbox chk-single">
                                <input type="checkbox" className="chk"
                                    id={"chk"+item.ID}
                                    name={"chk"+item.ID}
                                    onChange={(e) => handleCheck(e.target.checked, item.LOGIN_ID)}
                                    // 체크된 아이템 배열에 해당 아이템이 있을 경우 선택 활성화, 아닐 시 해제
                                    checked={checkItemsPage?.includes(item.LOGIN_ID) ? true : false}
                                    />
                                <label htmlFor={"chk"+item.ID} style={{padding : 0}}></label>
                            </div>
                        </td>
                    }

                    <td>{item.ORGANIZATION_NM}</td>
                    <td>{item.POSITION}</td>
                    <td>{item.LOGIN_ID}</td>
                    <td>{item.USER_NM}</td>
                </tr>
            )
        })
        : <tr><td colSpan="5">사용자가 없습니다.</td></tr>
    }
</tbody>

이건 개별 체크박스 표현 동작

PARTICIPANT_YN

로 분기를 나누어 disabled된 체크박스로도 표현해주었다

728x90
반응형

댓글