리액트 체크 박스 검색시 가장 많이 나오는
전체 체크박스 및 개별 체크박스
그치만 페이지를 이동하면 전체 체크박스가 새로고침 되기 때문에 다 날라간다
나는 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
반응형
'Front-end > React' 카테고리의 다른 글
[react-sortablejs] 리액트 순서 드래그 앤 드랍 (0) | 2023.04.14 |
---|---|
리액트 상태관리 라이브러리 React-Hook-Form (0) | 2023.03.16 |
[React] client IP / userAgent 정보 받기 (2) | 2022.10.06 |
[React] 다국어 기능 적용하기 react-i18next (1) | 2022.10.05 |
[React-spinner] loading spinner 적용하기 axios interseptor (1) | 2022.09.27 |
댓글