리액트 체크 박스 검색시 가장 많이 나오는
전체 체크박스 및 개별 체크박스
그치만 페이지를 이동하면 전체 체크박스가 새로고침 되기 때문에 다 날라간다
나는 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 |
댓글