TL;DR
- 데이터 그리드의 편집 기능은 변경된 셀과 이전 값, 유효성 검사, 실행 취소, 서버 전송 형식, 저장 실패 처리를 함께 다뤄야 하는 기능임.
@kanunilabs/datagrid-react-enterprise는 저장 전 편집 내용을 행 키 기준 변경 저장소에 보관하며, 저장이 성공하기 전까지 원본 데이터를 건드리지 않음.- 열별 규칙을 입력 중과 저장 시점에 검사하고,
Ctrl+Z와Ctrl+Y로 사용자 작업 단위의 실행 취소·다시 실행을 제공함. - 저장 시 변경된 열만 행별 핸들러로 보내며, 핸들러는 삽입·수정·삭제 순서로 한 번에 하나씩 실행되고 저장 요청도 직렬 처리됨.
- 한 요청이 실패하면 전체 저장이 실패하고 편집 내용은 남지만, 먼저 성공한 요청은 되돌리지 않으므로 완전한 원자성이 필요하면 트랜잭션을 사용해야 함.
편집 내용을 저장 전까지 데이터와 분리
- 데이터 그리드 라이브러리에서 가장 많이 요청되는 기능은 편집이며, Stack Overflow에서 가장 많이 읽힌 그리드 질문 중 하나는 “편집 후 행의 값을 어떻게 가져오는가?”임.
- 셀에 입력란을 추가하는 일보다 사용자가 어떤 셀을 바꿨는지, 이전 값은 무엇인지, 값이 허용되는지, 편집을 취소할 수 있는지, 서버에 어떤 형식으로 무엇을 보낼지, 서버가 거부하면 어떻게 할지가 더 어려운 문제임.
- 예시는 Online Retail II 데이터셋에서 가져온 주문 항목 240개를 사용함. 해당 항목은 영국 온라인 소매업체가 2011년 12월 첫째 주에 프랑스 고객에게 판매한 주문임.
- 데모의 서버는 페이지 안의 함수이며, 모든 요청을 로그에 기록해 저장 요청의 내용을 확인할 수 있음.
- 편집 내용을 행에 바로 쓰면 취소와 실행 취소를 위해 이전 값을 따로 기억해야 하고, 변경 사항을 확인하는 코드도 복잡해짐.
- 그리드는 편집 중인 변경 사항을 행 키로 구분한 별도 저장소에 보관하며, 저장이 성공할 때까지 원본 데이터에 반영하지 않음. 취소는 대기 중인 변경 사항을 버리는 작업임.
- 행 위치가 아니라 행 키로 변경 내용을 관리하므로 사용자가 정렬하거나 필터링하거나 다른 페이지로 이동한 뒤 돌아와도 편집 내용이 해당 레코드에 유지됨.
- 일괄 편집 모드에서는 사용자가 저장을 누를 때까지 변경 사항을 보류하며, 도구 모음은 전송될 행의 수를 표시함.
- 예시 설정은
@kanunilabs/datagrid-react-enterprise의EnterpriseDataGrid를 사용하고,id를 행 키로 지정함.description,quantity,price열만 수정 가능하며, 규칙과 업데이트 핸들러를 편집 설정에 연결함.
입력한 위치에서 잘못된 값 거부
- 열마다 규칙을 선언하며, 사용자가 입력하는 동안과 저장할 때 모두 규칙을 검사함.
description은 필수 항목이고,quantity는 1 이상이어야 하며 정수로 변환 가능한 정수 값이어야 함.price는 0.01 이상이어야 함.- 수량에
-5를 입력하면 편집기가 닫히지 않고 셀 아래에 이유를 표시함. - 화면 캡처를 준비하는 과정에서 오류 메시지가 올바른 위치에 렌더링되지만 보이지 않는 문제를 발견함. 셀이 넘치는 내용을 잘라내고, 다음 행이 편집 중인 행 위에 그려져 사용자에게는 빨간 밑줄만 보이고 이유는 표시되지 않았음.
- 이 문제는 2026년 10월 1일 공개된
@kanunilabs/datagrid-react-enterprise1.3.2에서 수정됨.
편집 되돌리기
Ctrl+Z는 실행 취소,Ctrl+Y는 다시 실행 단축키임.- 각 단계는 셀 하나가 아니라 사용자 작업 하나에 해당함. 따라서 셀 200개를 붙여넣은 작업을 취소하면 셀 하나가 아니라 붙여넣기 전체가 되돌려짐.
- 기본적으로 최근 100개 작업을 기록하며,
undo(),redo(),canUndo()공개 API를 제공하므로 도구 모음 버튼에서도 사용할 수 있음.
변경된 내용만 전송
- 사용자가 저장을 누르면 그리드가 변경된 각 행마다 핸들러를 한 번 호출하고, 변경된 열만 전달함.
- 예시 업데이트 핸들러는
/api/orders/${key}에PATCH요청을 보내며, 요청 본문은 변경된 값만 담은 JSON임. 이 형식은 REST 엔드포인트나UPDATE … SET쿼리에 적합함. - 세 행에서 각각 편집하면 로그에는 요청 세 건이 표시되며, 각 요청에는 해당 행에서 바뀐 필드 하나가 담김.
- 핸들러는 한 번에 하나씩 실행되며 순서는 삽입, 수정, 삭제임. 외래 키를 사용하는 백엔드에서는 부모 행이 이를 참조하는 자식 행보다 먼저 처리됨.
- 저장 요청도 직렬 처리됨. 이전에는 짧은 간격으로 저장을 두 번 누르면 두 요청이 동일한 대기 중 편집 내용을 대상으로 삼아 중복 전송할 수 있었으며, 이제 두 번째 저장은 첫 번째 저장이 끝날 때까지 기다림.
반환값의 중요성
- 그리드는 자체적으로 원본 데이터를 수정하지 않음. 업데이트 핸들러가 저장된 행을 반환하면 그리드가 해당 행을 채택하며 서버에서 계산된 값도 반영함.
- 핸들러가 아무것도 반환하지 않으면 그리드는 대기 중인 편집 내용을 지우고 원본 데이터를 그대로 둠. 이에 따라 셀에는 이전 값이 다시 표시됨.
- 데모의 첫 버전은 아무것도 반환하지 않아 저장할 때마다 변경 사항이 버려진 것처럼 보였음.
- 엔드포인트가 응답 본문을 반환하지 않는다면
{ ...row, ...values }를 반환하거나 저장 후 자체 상태를 갱신해야 함.
서버가 저장을 거부하는 경우
- 데모에서 “다음 저장 실패”를 선택하고 두 행을 수정해 저장하면 첫 번째 요청이 500 응답을 반환함.
- 요청 하나가 거부되면 전체 저장이 실패함. 모든 편집 내용은 대기 상태로 남고 표시와 저장 버튼의 행 수에도 계속 반영되므로 다시 입력하지 않고 재시도할 수 있음.
- 다만 실패한 요청보다 먼저 성공한 요청은 되돌리지 않음. 그리드는 서버에 기록된 쓰기를 취소하는 방법을 알지 못하며, 가능한 것처럼 가장하는 것보다 이 한계를 명확히 밝히는 편이 나음.
- 일괄 작업 전체가 성공하거나 실패해야 한다면 모든 변경 사항을 한 번에 받는
onSave를 사용하고 엔드포인트에서 트랜잭션을 적용해야 함. - 데모에서는 편집 두 건, 거부되는 값, 실행 취소, 남은 변경 사항만 전송하는 저장 과정을 한 번에 확인할 수 있음.
비용과 한계
- 편집, 유효성 검사, 실행 취소, CRUD 핸들러는 그리드의 Enterprise 에디션에 포함됨. 라이선스 키가 없으면 워터마크가 표시되며, 그 상태로 기능을 시험할 수 있음.
- 읽기 전용 그리드와 정렬, 필터링 등은 무료 Community 패키지에 포함됨.
- 대기 중인 편집 내용은 페이지 메모리에 보관되며 저장 전까지 유지됨. 데모는 새로고침 후에도 편집 내용을 유지하지 않음.
- 위와 같이 행별 핸들러를 사용하면 부분 일괄 처리가 가능함. 이는 REST API가 원하는 형태로 데이터를 전송하는 데 따르는 절충점임.
데모와 데이터 출처
- 데모 주소는
/demos/order-editing이며,/demos/order-editing?fail=1은 실패하는 서버 설정을 켠 상태로 열림. - 편집 문서에는 셀, 행, 폼, 팝업 모드와 CRUD 핸들러, 모든 규칙 유형이 설명되어 있음.
- 데이터 출처는 UCI Machine Learning Repository의 Online Retail II임. 인용 정보는 Chen, 2019이며 라이선스는 CC BY 4.0임.
- 글은 AI의 도움을 받아 작성됐으며, 데모와 설명된 각 동작은 2026년 10월 패키지 및 공개 데이터셋과 대조해 확인됨.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요