게으른개발너D
[React] Handsontable 1 - 설치 및 데이터 추가 본문
Handsontable을 이용하여 간단한 기능을 구현하려다 의외로 개고생을 하여 기록한다.
https://handsontable.com/docs/react-data-grid/
Handsontable은 React-Data-Grid를 기반으로 하는 라이브러리로, 엑셀과 유사한 기능을 제공한다.
공식 문서에서 자세한 내용을 확인할 수 있다.
React를 이용한 demo는 여기에서 확인할 수 있다.
https://codesandbox.io/s/handsontable-react-data-grid-hello-world-app-13-1-0-fdv2lc
1. 구현할 내용
이름 | 생년월일 | 모임 | 만남 횟수 |
James | 1999-08-30 | 알고리즘 | 2 |
Emily | 2000-12-24 | 프론트엔드 | 5 |
Amber | 1988-06-14 | 알고리즘 | 3 |
Lisa | 1994-07-03 | 돼지파티 | 13 |
1. 해당 내용을 table data로 넣는다.
2. 이름, 생년월일, 모임 열은 내용을 수정할 수 없다.
3. 컨텍스트메뉴 기능을 넣어 행과 열을 추가하거나 삭제할 수 있다. (1행은 삭제하지 못한다.)
4. 저장 버튼을 클릭 시 console.log로 삭제된 행과 열에 대한 정보를 출력한다.
5. 새로운 행이 추가 되었을 시, 저장 버튼을 누르면 해당 행의 이름, 생년월일, 모일 열은 수정할 수 없게된다.
point 🤔
여기서 포인트이면서 문제가 되는 게 readonly를 적용해야하는 열(이름, 생년월일, 모임)이 있다는 점이다.
이게 왜 문제가 되냐하면 handsontable의 데이터는 배열로 받고, 특정한 열에 readonly를 적용하게 되면 그건 배열 index에 적용이 된다. 하지만 행이나 열을 추가하게 되면 readonly를 적용한 열의 index가 바뀐다는 점.
그리고 행을 추가할 시 새로운 행의 이름, 생년월일, 모임 부분은 내용을 넣을 수 있도록 readonly가 적용되지 않아야된다.
일단 천천히 구현해보자.
2. handsontable 설치
먼저 create-react-app으로 react 프로젝트를 만든다. typescript로 구현할 예정이며 프로젝트 이름은 manage_crew로 정하였다.
1. handsontable 설치
$ npm install handsontable @handsontable/react
해당 명령어를 입력하여 handsontable for react를 설치한다.
package.json을 확인하면 dependencies에 @handsontable/react 와 handsontable가 설치되어 있다.
src 디렉토리엔 index.tsx와 App.tsx만 남겨두었고 App.tsx에서 모두 구현할 예정이다.
2. css import
// App.tsx
import 'handsontable/dist/handsontable.full.min.css';
hansontable css를 import 한다.
3. hansontable modules
// App.tsx
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
import 'handsontable/dist/handsontable.full.min.css';
registerAllModules();
registerAllModules(); 를 사용하면 handsontable의 모든 모듈을 한번에 가져올 수 있다.
https://handsontable.com/docs/react-data-grid/modules/
물론 위 링크에서 필요한 모듈을 찾아서 따로 추가할 수도 있다.
4. HotTable Component
// App.tsx
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
import { HotTable } from '@handsontable/react';
import './App.css';
import 'handsontable/dist/handsontable.full.min.css';
import Button from './components/Button';
registerAllModules();
function App() {
const handleClickSave = () => {};
return (
<div className="App">
<Button callback={handleClickSave}>저장</Button>
<HotTable
licenseKey="non-commercial-and-evaluation"
height="auto"
widht="auto"
/>
</div>
);
}
export default App;
import { HotTable } from '@handsontable/react';
HotTable 컴포넌트를 부르면 기본적인 엑셀 테이블 만들기는 준비되었다.
상업적 이용으로 사용하는게 아닐 경우 컴포넌트에 licenseKey="non-commercial-and-evaluation" 를 추가한다.
참고로 저장 버튼은 컴포넌트로 따로 분리하였다.
5. add props
내용을 추가하기 위해 HotTable의 props를 추가해주자.
먼저 src 위치에 default_data.ts 파일을 만들어 위의 테이블 데이터를 2차 배열로 나타내었다.
// default_data.ts
export const DEFAULT_DATA = [
['이름', '생년월일', '모임', '만남 횟수'],
['James', '1999-08-30', '알고리즘', 2],
['Emily', '2000-12-24', '프론트엔드', 5],
['Amber', '1988-06-14', '알고리즘', 3],
['Lisa', '1994-07-03', '돼지파티', 13],
];
기본적인 데이터는 data prop으로 채울 수 있다.
데이터와 관련없는 props는 HOTTABLE_PROPS 변수로 따로 분리해주었다.
// App.tsx
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
import { HotTable } from '@handsontable/react';
import './App.css';
import 'handsontable/dist/handsontable.full.min.css';
import Button from './components/Button';
import { DEFAULT_DATA } from './default_data';
registerAllModules();
const HOTTABLE_PROPS = {
height: 'auto',
width: 'auto',
licenseKey: 'non-commercial-and-evaluation',
};
function App() {
const handleClickSave = () => {};
return (
<div className="App">
<Button callback={handleClickSave}>저장</Button>
<HotTable data={DEFAULT_DATA} {...HOTTABLE_PROPS} />
</div>
);
}
export default App;
3. context menu
https://handsontable.com/docs/react-data-grid/context-menu/
오른쪽 마우스를 클릭했을 때 context menu가 나오게 하려면 prop으로 contextMenu를 쓰면 된다.
// App.tsx
function App() {
const handleClickSave = () => {};
return (
<div className="App">
<Button callback={handleClickSave}>저장</Button>
<HotTable data={DEFAULT_DATA} contextMenu={true} {...HOTTABLE_PROPS} />
</div>
);
}
이렇게 행과 열의 추가, 삭제, readonly까지 지정할 수 있다.
하지만 우리가 사용할 건 행과 열의 추가와 삭제뿐이니 context menu로 사용할 메뉴를 지정해주자
// App.tsx
import { Settings } from 'handsontable/plugins/contextMenu';
...
const CONTEXT_MENU: Settings = [
'row_above',
'row_below',
'---------',
'col_left',
'col_right',
'---------',
'remove_col',
'remove_row',
];
...
function App() {
const handleClickSave = () => {};
return (
<div className="App">
<Button callback={handleClickSave}>저장</Button>
<HotTable
data={DEFAULT_DATA}
contextMenu={CONTEXT_MENU}
{...HOTTABLE_PROPS}
/>
</div>
);
}
'프로젝트 > Side Project' 카테고리의 다른 글
[React] Handsontable 3 - useRef, hooks, and closure issue (0) | 2023.11.16 |
---|---|
[React] Handsontable 2 - headers and columns for readonly (0) | 2023.11.05 |
[TS] BlockChain 1 - Targets (0) | 2023.04.04 |
[JS] Analog Clock (0) | 2023.03.24 |
[JS] JavaScript Drum Kit (0) | 2023.03.24 |