reopt designreopt design
DocsExploreToolsPricingBuilder
Start
Start
Playground
Core Concepts
Core Concepts
DataGrid
DataGrid 개요
Editable Data Entry
Operations Monitoring
Large Data
Remote Protocol
Migration Playbook
App Composition Guide
Column Playbook
Build & Operate
Skills
Release Notes
Reference
Hook Reference
Type Reference
Oopt-datagrid
reopt designreopt design

A design system for the AI era

  • Docs
  • Pricing
  • Releases
  • GitHub
  • Terms of Service
  • Privacy Policy

© 2026 reopt-ai. All rights reserved.

Core Concepts
  1. Docs
  2. /
  3. Core Concepts
  4. /
  5. Core Concepts

핵심 개념

컬럼 정의, 셀 편집 파이프라인, 가상화 모델, 선택/클립보드 아키텍처

reopt design · Updated Jun 26, 2026

시작하기핵심 개념개요편집형 데이터 입력운영 모니터링대규모 데이터원격 연동 계약마이그레이션 플레이북앱 조합 가이드컬럼 설계 플레이북Skills릴리즈 노트Hook 레퍼런스타입 레퍼런스

1. 컬럼 정의

DataGridColumn<Row, Value>는 하나의 컬럼을 정의하는 핵심 인터페이스입니다. 표시, 편집, 레이아웃을 모두 이 객체 안에서 선언합니다.

속성필수설명
idO유니크 식별자. 정렬/클립보드/캐시에서 키로 사용
titleO헤더에 표시되는 텍스트
getValueO(row: Row) => Value — 셀 표시 값 추출
setValue편집 시(row: Row, value: Value) => Row — 불변 업데이트 반환
width / minWidth / maxWidth픽셀 단위 너비. 기본값 150px, 리사이즈 범위 제한
resizable드래그 리사이즈 허용 여부 (기본 true)
align"left" | "center" | "right"
group같은 group 값을 가진 컬럼끼리 헤더를 합침
tsx
const columns: DataGridColumn<Product>[] = [
  {
    id: "name",
    title: "상품명",
    getValue: (row) => row.name,
    width: 200,
    minWidth: 120,
    resizable: true,
  },
  {
    id: "price",
    title: "가격",
    getValue: (row) => row.price,
    align: "right",
    width: 100,
    group: "금액",
  },
  {
    id: "tax",
    title: "세금",
    getValue: (row) => row.price * 0.1,
    align: "right",
    width: 100,
    group: "금액",
  },
];

2. 셀 편집 파이프라인

사용자 입력이 최종 데이터에 반영되기까지 5단계 파이프라인을 거칩니다. 각 단계에서 변환, 검증, 거부가 가능합니다.

text
User Input
  → parseInput(raw)          // 문자열 → 타입 변환 (예: "42" → 42)
  → validateValue(parsed)    // 유효성 검증, 에러 메시지 반환
  → setValue(row, validated)  // 불변 Row 업데이트 반환
  → onCellsEdited(changes)   // 배치 편집 인터셉트 (paste/delete 포함)
  → onRowsChange(newRows)    // 최종 상태 업데이트

빌트인 에디터 종류

kind용도주요 옵션
text단일 행 텍스트maxLength, placeholder
textarea여러 줄 텍스트rows, maxLength
number숫자 입력min, max, step, decimals
select드롭다운 선택options, allowEmpty
checkbox불리언 토글indeterminate
date날짜 선택format, minDate, maxDate
async-combobox비동기 검색 + 선택loadOptions, debounceMs
custom커스텀 편집기 컴포넌트component, provideEditor
tsx
{
  id: "price",
  title: "가격",
  getValue: (row) => row.price,
  setValue: (row, value) => ({ ...row, price: value as number }),
  editable: true,
  editor: { kind: "number", min: 0, max: 999999, step: 100, decimals: 0 },
  // 문자열 입력을 숫자로 변환
  parseInput: (raw) => Number(raw.replace(/,/g, "")),
  // 음수 값 거부
  validateValue: (val) =>
    val < 0 ? { valid: false, message: "음수 불가" } : { valid: true },
}

3. 가상화 모델

DataGrid는 행(row)과 열(column) 모두 가상화하여 수만 행 이상의 데이터에서도 일정한 렌더링 성능을 유지합니다.

옵션기본값설명
rowBufferPx300뷰포트 위/아래에 미리 렌더링할 픽셀 버퍼. 스크롤 시 빈 영역 방지
columnOverscan2뷰포트 좌/우에 추가 렌더링할 컬럼 수
maxRenderedRows500한 번에 렌더링할 최대 행 수 상한. 비정상 스크롤 방지용
scrollUpdateModerafsync — 매 스크롤 이벤트마다 동기 업데이트. raf — requestAnimationFrame으로 배치 처리
valueCachefalsetrue 시 getValue 결과를 캐시. 스크롤/선택 중 재계산 방지
valueCacheStrategyrow-refrow-ref — 객체 레퍼런스로 invalidation. row-id — getRowId 기반 (sort/reorder에 안정적)
rendererRefreshModeautoauto — 값 변경 시 자동 리렌더. manual — 컬럼별 refreshCellRenderer 콜백으로 제어
tsx
<DataGrid
  columns={columns}
  rows={rows}
  height={600}
  getRowId={(row) => row.id}
  // 가상화 튜닝
  rowBufferPx={400}
  columnOverscan={3}
  maxRenderedRows={300}
  scrollUpdateMode="raf"
  // 값 캐시
  valueCache
  valueCacheStrategy="row-id"
/>

4. 선택 모델

DataGridSelection은 시작 셀(start)과 끝 셀(end)로 정의되는 직사각형 영역입니다. 행 선택과 컬럼 선택은 별도 모드로 제어합니다.

옵션값설명
rowSelectnone | single | multi행 선택 모드. multi에서 Shift+Click 범위 선택, Ctrl+Click 토글
columnSelectboolean헤더 클릭으로 전체 컬럼 선택 허용
rowMarkersnone | number | checkbox | both왼쪽 행 마커 표시 유형. checkbox는 multi-select 전용
tsx
const [selection, setSelection] = useState<DataGridSelection>();

<DataGrid
  columns={columns}
  rows={rows}
  height={400}
  rowSelect="multi"
  rowMarkers="checkbox"
  columnSelect
  selection={selection}
  onSelectionChange={setSelection}
/>

5. 클립보드

복사(Copy)와 붙여넣기(Paste)는 TSV(Tab-Separated Values) 형식을 기본으로 사용합니다. 스프레드시트 앱과의 호환이 자연스럽게 동작합니다.

- Copy: serializeValue(value) → 클립보드 TSV 텍스트

- Paste: 클립보드 TSV → deserializeValue(text) → validateValue → setValue

- Cross-column paste: coercePasteValue로 다른 타입의 컬럼에 붙여넣기 변환 가능

tsx
const columns: DataGridColumn<Row>[] = [
  {
    id: "status",
    title: "상태",
    getValue: (row) => row.status,
    setValue: (row, val) => ({ ...row, status: val as string }),
    editable: true,
    // 복사 시 한글 라벨로 직렬화
    serializeValue: (val) =>
      val === "active" ? "활성" : val === "paused" ? "일시정지" : "비활성",
    // 붙여넣기 시 역변환
    deserializeValue: (text) =>
      text === "활성" ? "active" : text === "일시정지" ? "paused" : "inactive",
  },
];

<DataGrid
  columns={columns}
  rows={rows}
  height={400}
  copyHeaders          // 복사 시 헤더 행 포함
  maxPasteCells={5000} // 붙여넣기 최대 셀 수 제한
  onCopy={(ctx) => {
    console.log("복사:", ctx.selection, ctx.cells);
  }}
  onPaste={(ctx) => {
    // false 반환 시 붙여넣기 취소
    if (ctx.cells.length > 1000) return false;
    return true;
  }}
/>

6. Row Identity

getRowId는 각 행의 안정적인 식별자를 반환합니다. 지정하지 않으면 배열 인덱스가 사용되지만, 정렬이나 필터링 시 캐시 무효화와 키 충돌이 발생합니다.

권장: 실무 프로젝트에서는 반드시 getRowId를 지정하세요. 정렬, Undo/Redo, Remote Sync, Value Cache 모두 getRowId에 의존합니다.

valueCacheStrategyinvalidation 기준적합한 경우
row-ref객체 레퍼런스 (===)정렬/필터 없이 배열 순서가 고정인 경우
row-idgetRowId 반환값정렬, 필터, 재정렬이 빈번한 경우 (권장)
tsx
// DB의 PK나 UUID를 안정적인 식별자로 사용
<DataGrid
  columns={columns}
  rows={rows}
  getRowId={(row) => row.uuid}
  valueCache
  valueCacheStrategy="row-id"
  height={400}
/>
PreviousStart패키지 설치, .npmrc 설정, 첫 DataGrid 렌더링까지의 빠른 시작 가이드Start
Go to Start
NextDataGrid 개요편집형, 운영 모니터링형, 대규모 데이터 시나리오로 나눈 DataGrid 실전 가이드DataGrid