본문 바로가기
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
반응형

댓글