React

[React] ag grid Row Data Transaction

판교너굴맨 2022. 10. 31. 00:32

기존에 사용하던 Ant Design라이브러리 Table을 Ag grid로 변경하게 되었다.

Ant D Table은 Row Data를 useState hook을 통해 직접 변경해야 했다면 Ag grid에서는 useState hook을 사용하지 않고, applyTransaction이라는 내장 함수를 통해 Row Data를 변경할 수 있다.

applyTransaction:
Update row data.
Pass a transaction object with lists for add, remove and update
행 데이터를 업데이트합니다.
추가 제거 및 업데이트 목록과 함께 트랜잭션 객체를 전달합니다.

 

1. 환경 설정 

1-1. Ag Grid 설치 (무료 버전만 사용 시)

# npm
npm i ag-grid-community ag-grid-react

# yarn
yarn add ag-grid-community ag-grid-react

1-2. Start Ag Grid

import React, { useRef, useState } from "react";
import { AgGridReact } from "ag-grid-react";

import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";

export default function App() {
  // Optional - for accessing Grid's API
  const gridRef = useRef();
  
  // Set rowData to Array of Objects, one Object per Row
  const [rowData] = useState([
    { number: 1 },
    { number: 2 },
    { number: 3 }
  ]);

  // Each Column Definition results in one Column.
  const [columnDefs] = useState([
    { field: "number" }
  ]);

  return (
    {/* On div wrapping Grid a) specify theme CSS Class Class and b) sets Grid size */}
    <div className="ag-theme-alpine" style={{ height: 300, width: 300 }}>
      <AgGridReact
        ref={gridRef}
        rowData={rowData}
        columnDefs={columnDefs}
      ></AgGridReact>
    </div>
  );
}

1-3. Version

2022-10-30 기준 버전 

package.json

{
	"ag-grid-community": "^28.2.0",
	"ag-grid-react": "^28.2.0",
}

 

2. Example

2-1. Read

해당 Grid의 모든 Row Data 정보를 확인하거나 return 값으로 반환할 수 있다.

forEachNode: 그리드의 각 노드(행)를 반복하고 각 노드에 대한 콜백을 호출한다. javascript의 forEach와 유사하게 동작한다.

export default function App() {
  const getRowData = () => {
    const rowData = [];
    gridRef.current.api.forEachNode(function (node) {
      rowData.push(node.data);
    });
    console.table("Row Data:", rowData);
    return rowData;
  };

  return (
    <button onClick={getRowData}>Get Row Data</button>
  );
}

 

2-2. Row Add

랜덤한 Number 값으로 Row Data를 추가한다.

export default function App() {
  const getRandomNumber = () => {
    return Math.floor(Math.random() * 10);
  };
  
  const addItems = () => {
    const randomNumber = getRandomNumber();
    const newItems = [
      {
        number: randomNumber,
      },
    ];
    gridRef.current.api.applyTransaction({
      // add: 새로 추가할 row Data
      add: newItems, 
    });
  };

  return (
    <button onClick={addItems}>Add Item</button>
  );
}

 

add 외에 addIndex속성도 사용할 수 있는데 addIndex속성에 값을 값을 넣으면 해당 index의 row부터 추가되게 된다.

 

gridRef.current.api.applyTransaction({
  // add: 새로 추가할 row Data
  add: newItems,
  // addIndex: 새로 추가될 index 위치
  addIndex: 2
});

 

2-3 Update

코드를 간단하게 구현하기 위해 index가 2인 Row Data만 새로운 값으로 업데이트한다.

export default function App() {
  const getRandomNumber = () => {
    return Math.floor(Math.random() * 10);
  };
  
  const updateItems = () => {
    const itemsToUpdate = [];
    gridRef.current.api.forEachNode((rowNode, index) => {
      // index가 2인 rowData를 update
      if (index === 2) {
        const data = rowNode.data;
        data.number = getRandomNumber();
        itemsToUpdate.push(data);
      }
      return;
    });
    gridRef.current.api.applyTransaction({ update: itemsToUpdate });
  };

  return (
    <button onClick={updateItems}>Update Item index = 2</button>
  );
}

 

2-4 Remove

선택한 row를 제거한다.

getSelectedRows: 선택된 행 목록을 반환한다.

export default function App() {
  const onRemoveSelected = () => {
    const selectedData = gridRef.current.api.getSelectedRows();
    gridRef.current.api.applyTransaction({ remove: selectedData });
  };

  return (
    <div>
      <button onClick={onRemoveSelected}>Remove Select</button>
      <div className="ag-theme-alpine" style={{ height: 300, width: 300 }}>
        <AgGridReact
          ref={gridRef}
          rowData={rowData}
          columnDefs={columnDefs}
          rowSelection={"single"}  {/* row를 선택하기 위해 필요 */}
        ></AgGridReact>
      </div>
    </div>
  );
}

 

2-5 전체 코드

import React, { useRef, useState } from "react";
import { AgGridReact } from "ag-grid-react";

import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";

export default function App() {
  const gridRef = useRef();
  const [rowData] = useState([{ number: 1 }, { number: 2 }, { number: 3 }]);

  const [columnDefs] = useState([{ field: "number" }]);

  const getRandomNumber = () => {
    return Math.floor(Math.random() * 10);
  };

  const getRowData = () => {
    const rowData = [];
    gridRef.current.api.forEachNode(function (node) {
      rowData.push(node.data);
    });
    console.table("Row Data:", rowData);
    return rowData;
  };

  const addItems = () => {
    const randomNumber = getRandomNumber();
    const newItems = [
      {
        number: randomNumber,
      },
    ];
    gridRef.current.api.applyTransaction({
      add: newItems,
    });
  };

  const updateItems = () => {
    const itemsToUpdate = [];
    gridRef.current.api.forEachNode((rowNode, index) => {
      if (index === 2) {
        const data = rowNode.data;
        data.number = getRandomNumber();
        itemsToUpdate.push(data);
      }
      return;
    });
    gridRef.current.api.applyTransaction({ update: itemsToUpdate });
  };

  const onRemoveSelected = () => {
    const selectedData = gridRef.current.api.getSelectedRows();
    gridRef.current.api.applyTransaction({ remove: selectedData });
  };

  return (
    <div>
      <div>
        <button onClick={addItems}>Add Item</button>
        <button onClick={getRowData}>Get Row Data</button>
        <button onClick={updateItems}>Update Item index = 2</button>
        <button onClick={onRemoveSelected}>Remove Select</button>
      </div>
      <div className="ag-theme-alpine" style={{ height: 300, width: 300 }}>
        <AgGridReact
          ref={gridRef}
          rowData={rowData}
          columnDefs={columnDefs}
          rowSelection={"single"}
        ></AgGridReact>
      </div>
    </div>
  );
}

 

2-6 출력 화면

 

3. 참고 자료

위의 예제는 ag grid react에서 Client-Side Data / Transaction 항목에서 확인할 수 있다.

https://www.ag-grid.com/react-data-grid/data-update-transactions/

 

React Data Grid: Client-Side Data - Transaction Updates

Transaction Updates allow large numbers of rows in the grid to be added, removed or updated in an efficient manner. Download v28 of the best React Data Grid in the world now.

www.ag-grid.com

https://www.ag-grid.com/react-data-grid/grid-api/

 

React Data Grid: Grid API

All of these grid methods are available through the api property of GridOptions . Download v28 of the best React Data Grid in the world now.

www.ag-grid.com