배치 저장과 복원
배치 저장과 복원의 흐름
섹션 제목: “배치 저장과 복원의 흐름”위젯을 이동하거나 크기를 조절하면 DashboardGrid가 좌표를 계산합니다. onLayoutCommit을 commands.applyLayoutSnapshot에 연결하여 React 상태를 동기화한 뒤 저장합니다. 이 연결이 없으면 화면에서 변경한 좌표와 저장 대상 상태가 달라질 수 있습니다.
- 배치 저장으로 현재 전체 상태를 메모리에 보관합니다.
- 너비 변경을 누르거나 위젯 제목을 드래그합니다.
- 저장 상태 복원으로 저장한 배치를 되돌립니다.
이 예제의 저장소는 React 메모리입니다. 새로고침 후에도 유지하려면 직렬화 가능한 데이터를 선택하고 애플리케이션 저장소에 기록해야 합니다.
import { useState } from 'react';import { DashboardGrid, useDashboardGrid, type DashboardWidget, type DashboardStateSnapshot } from 'comins-grid-layout';import 'gridstack/dist/gridstack.min.css';import 'comins-grid-layout/styles.css';
export default function GridDemo({ lang = 'ko' }: { lang?: string }) { const ko = lang === 'ko'; const initialWidgets: DashboardWidget[] = [ { id: 'overview', title: ko ? '프로젝트 개요' : 'Project overview', layout: { id: 'overview', x: 0, y: 0, w: 6, h: 2 } }, { id: 'activity', title: ko ? '최근 활동' : 'Recent activity', layout: { id: 'activity', x: 6, y: 0, w: 6, h: 2 } }, ]; const grid = useDashboardGrid({ initialColumns: 12, initialWidgets }); const [saved, setSaved] = useState<DashboardStateSnapshot | null>(null); const [status, setStatus] = useState(ko ? '제목을 드래그하여 배치를 바꿀 수 있습니다.' : 'Drag a title to rearrange the widgets.'); return <div className="demo grid-demo" data-demo="grid"> <div className="demo-toolbar"> <button onClick={() => { setSaved(grid.commands.serializeState()); setStatus(ko ? '현재 배치를 메모리에 저장했습니다.' : 'Saved this layout in memory.'); }}>{ko ? '배치 저장' : 'Save layout'}</button> <button onClick={() => { grid.commands.updateWidgetLayout('overview', { w: 3 }); setStatus(ko ? '첫 위젯의 너비를 변경했습니다.' : 'Changed the first widget width.'); }}>{ko ? '너비 변경' : 'Change width'}</button> <button disabled={!saved} onClick={() => { if (saved) { grid.commands.restoreLayout(saved); setStatus(ko ? '저장한 배치를 복원했습니다.' : 'Restored the saved layout.'); } }}>{ko ? '저장 상태 복원' : 'Restore saved'}</button> <button onClick={() => { grid.commands.resetLayout(); setSaved(null); setStatus(ko ? '초기 상태로 돌아왔습니다.' : 'Reset to the initial layout.'); }}>{ko ? '초기화' : 'Reset'}</button> </div> <DashboardGrid widgets={grid.widgets} columns={grid.columns} refreshKey={grid.refreshVersion} editable movable resizable showControls={false} engineOptions={{ cellHeight: 70, margin: 6, animate: false }} onLayoutCommit={grid.commands.applyLayoutSnapshot} renderWidget={(widget) => <div className="widget-content"><span className="widget-number">{widget.id === 'overview' ? '03' : '12'}</span><span>{widget.id === 'overview' ? (ko ? '함께 만드는 모듈' : 'Modules to build with') : (ko ? '열로 구성한 작업 공간' : 'Columns in your workspace')}</span></div>} /> <p role="status" className="demo-status">{status}</p> <details><summary>{ko ? '현재 레이아웃 JSON' : 'Current layout JSON'}</summary><pre data-layout>{JSON.stringify(grid.commands.serializeLayout(), null, 2)}</pre></details> </div>;}어떤 snapshot을 저장할까?
섹션 제목: “어떤 snapshot을 저장할까?”| 메서드 | 입력 / 반환 | 용도 |
|---|---|---|
serializeLayout() |
DashboardLayoutSnapshot 반환 |
현재 컬럼 수와 위젯 좌표만 조회합니다. |
serializeState() |
DashboardStateSnapshot<TData> 반환 |
위젯 데이터, 최대화·최소화 복원 좌표, 방문한 컬럼별 좌표까지 저장합니다. |
applyLayoutSnapshot(snapshot) |
DashboardLayoutSnapshot → void |
Grid의 배치 commit을 상태에 반영합니다. |
restoreLayout(snapshot) |
DashboardStateSnapshotInput<TData> → void |
전체 상태를 교체하여 복원합니다. |
resetLayout(snapshot?) |
좌표 또는 상태 snapshot → void |
인자가 없으면 초기 상태로, 인자가 있으면 해당 snapshot으로 교체합니다. |
DashboardStateSnapshot
섹션 제목: “DashboardStateSnapshot”| 필드 | 타입 | 의미 |
|---|---|---|
columns |
DashboardColumnCount |
현재 컬럼 수 |
widgets |
DashboardWidget<TData>[] |
현재 위젯, 좌표, 데이터와 상태 |
previousLayouts |
Record<DashboardWidgetId, DashboardWidgetLayout> |
최대화·최소화에서 복원할 좌표 |
layoutsByColumn |
DashboardLayoutsByColumn |
방문한 컬럼별 레이아웃 캐시 |
DashboardLayoutSnapshot의 widgets는 전체 위젯이 아닌 DashboardWidgetLayout[]입니다. 두 snapshot을 서로 바꾸어 사용하지 않습니다.
복원 계약
섹션 제목: “복원 계약”restoreLayout 입력은 이전 버전과의 호환을 위해 previousLayouts, layoutsByColumn 생략을 허용합니다. 활성 컬럼 캐시와 최상위 상태가 다르면 최상위 widgets와 previousLayouts가 우선합니다. React 외부 reducer에서는 serializeDashboardState 순수 helper를 사용할 수 있습니다.
저장소 선택, schema migration, 서버 동기화는 소비자 애플리케이션의 책임입니다. 외부 JSON은 타입·ID·좌표·업무 데이터 검증을 마친 뒤 복원합니다. TypeScript 타입 표기는 런타임 JSON 검증을 대신하지 않습니다.
검색어
섹션 제목: “검색어”배치 저장, 레이아웃 저장, 상태 저장, 영속화, 복원, persistence, serializeState, restoreLayout.