상세 컨텐츠

본문 제목

React(리액트) 티키타카 25 (AG-Grid 활용 1)

React

by e7e 2025. 3. 14. 00:17

본문

2022.10.26 - [자바스크립트] - ag-grid 간단 사용법(사용법 쪼메 바뀜!)

글은 이제 보닝, 아주 오래 되었당. 맘에 걸렸는데, 잘 되었당.

다시 쓰자니, 귀찮았는데 React를 기반으로 쓴다면 또 다른 맛의 향과 열매당.

 

React에선 사용법이 더욱 쉽당. (자동완성의 힘은 항상 게으른 날 유혹한다)

API나 컴포넌트는 항상 그것을 제공하는 홈페이지의 설명으로 부터 시작하장.

https://www.ag-grid.com/

그곳에서 React를 클릭하여 스스로 공부 (Self-Study)가 가능하다면 당신은 이미 날 업고 넘었다.

 

성격이 급하고 뽀인또만 뽑고 싶은 사람들은 지금부터 나와 함께 출발하장. 

이제는 생략하고픈 아래와 같은 과정을 이젠 본능적으로 하자

1. 이름 영어로 아무렇게나  어딘가 나중에도 찾기 쉬운 곳에 새 폴더를 만들공
2. vscode로 해당 폴더를 연 후, 터미널 열공 
3. npx create-vite@latest .     명령으로 필요한 파일들 현재 폴더에 다운로드
4. npm i                                  명령으로 package.json 파일에 기술된 모듈들 설치
5. 필요 없는 파일들(App.css 등등..)  정리하고 
6. npm i ag-grid-react             명령으로 react에 쓸 ag-gride 모듈 설치
7. npm run dev 
8. 영문자 O 누르고 엔터  눌러 브라우져 열기

둔비 끄읕  

 

디금부터 이야기는 대부분 ag-grid 홈페이지에 기술된 내용을 바탕으로 한당.(오켕?)

 

GridExam.jsx  (시작 템플릿으로 생각하장)

import { AllCommunityModule, ModuleRegistry } from "ag-grid-community";
import { AgGridReact } from "ag-grid-react";
ModuleRegistry.registerModules([AllCommunityModule]);

function GridExam() {
  return (
    <div style={{ height: 500 }}>
      <AgGridReact />
    </div>
  );
}

export default GridExam;

주의: 나도 자주하는 실수인데, AgGridReact는 부모 크기에 맞춰서 그려지기 때문에

부모 div 에 height를 주지 않으면 화면에 암것도 안나온단당.

 

App.jsx 

import GridExam from "./GridExam";

function App() {
  return (
    <>
      <h1
        style={{
          textAlign: "center",
          backgroundColor: "blueviolet",
          color: "white",
        }}
      >
        띠이작 E7E랑
      </h1>
      <GridExam />
    </>
  );
}

export default App;

여기 까지만 하고 화면 결과를 보면, 데이타가 없다거나 아니면 Loading이라고 만 보일거당.

틀린 말이 아니라 맞는 말이라서 놀랍당. 콤푸타가 꽤 똑똑하단 느낌이 갑자기 엄습한다.

 

이제  잘 뿌리는지 데이타를 주어보자. 

AgGridReact 컴포넌트에는 rowData와 columnDefs 속성이 제공되어, 여기에 뿌릴 데이터

어떤 컬럼형태를 가질건지, 컬럼에는 어떤 기능을 부여할 건지를 알려주어야 한당.

 

아래 처럼 GridExam.jsx를 고쳐보장.

 GridExam.jsx

import { AllCommunityModule, ModuleRegistry } from "ag-grid-community";
import { AgGridReact } from "ag-grid-react";
ModuleRegistry.registerModules([AllCommunityModule]);

function GridExam() {
  return (
    <div style={{ height: 500 }}>
      <AgGridReact
        rowData={[
          { name: "슈퍼맨", age: 40, job: "기자" },
          { name: "배트맨", age: 50, job: "부자" },
          { name: "원더우먼", age: 30, job: "고고학자" },
        ]}
        columnDefs={[
          { field: "name", headerName: "이름" },
          { field: "job", headerName: "직업" },
          { field: "age", headerName: "나이" },
        ]}
      />
    </div>
  );
}

export default GridExam;

화면 결과를 보면, 머릿속에 매칭관계가 느껴질거당.

columnDefs에 정의된 순서대로 컬럼이 나옴은 주의 뽀인또당.

컬럼을 잡아 끌어도 보고, 밖으로 던져도 보고, 클릭(sort동작)도 해보장.

눈으로 본 것들이 기본 제공되는 동작들이다. (오켕?)

 

소스가 너무 하드코딩스럽게 하드하게 보이닝, 장기적 관점에서 손을 조금 보장.

src 아래에 dummy라 폴더를 만들고, data.js란 파일을 아래 처럼 만들장.

[ 그저 가짜데이터를 만들고, 컬럼 정의를 한 것 뿌니니 복사/붙여넣기 권장 ]

 

data.js

// 이미티콘 단축키는 window키와 함께 ;를 또는 window키와 함께 .을 눌러줘용
const emoticons = [
  "👩",
  "👧",
  "👵",
  "👩‍🦰",
  "👱",
  "👸",
  "🤶",
  "👮‍♀️",
  "🕵️‍♀️",
  "👩‍⚕️",
  "👩‍🎓",
  "👰",
  "👩‍🏫",
  "👩‍⚖️",
  "👩‍🍳",
  "👩‍🏭",
  "👩‍💼",
  "👩‍🔬",
  "👩‍💻",
  "👩‍🎨",
  "👩‍✈️",
  "👩‍🚀",
  "🧕",
];

// 랜덤 데이터용 seed
const fsName = "가나다라마바사아자차카타파하";
const fsNames = fsName.split("");
const esNames = ["우니", "시니", "이니", "혀니", "나니"];
const features = [
  "두리번",
  "왕부자",
  "배불뚝",
  "똑똑이",
  "초현명",
  "신내림",
  "훈수꾼",
  "디버거",
  "무질서",
];

// 랜덤 데이터 생성 함수들
const ranEmoji = () => emoticons[Math.floor(Math.random() * emoticons.length)];
const ranAge = () => Math.round(Math.random() * 10) + 20;
const ranName = () =>
  fsNames[Math.floor(Math.random() * fsNames.length)] +
  esNames[Math.floor(Math.random() * esNames.length)];
const ranFeature = () => features[Math.floor(Math.random() * features.length)];
const ranYear = Math.round(Math.random() * 24) + 2000;
let ranMonth = Math.ceil(Math.random() * 12);
ranMonth = ranMonth < 10 ? "0" + ranMonth : ranMonth;
let ranDay = Math.ceil(Math.random() * 28);
ranDay = ranDay < 10 ? "0" + ranDay : ranDay;
const ranDate = () => `${ranYear}-${ranMonth}-${ranDay}`;

// 초기 가짜 데이터
const rowData = [
  {
    name: "추우니",
    feature: "탑모델",
    passdate: "2024-10-10",
    age: ranAge(),
    gisa: true,
  },
  {
    name: "영시니",
    feature: "귀요미",
    passdate: "2024-11-11",
    age: ranAge(),
    gisa: true,
  },
  {
    name: "세이니",
    feature: "매니저",
    passdate: "2024-12-12",
    age: ranAge(),
    gisa: true,
  },
  {
    name: "지혀니",
    feature: "브레인",
    passdate: "2025-01-01",
    age: ranAge(),
    gisa: true,
  },
  {
    name: "사나니",
    feature: "옌예인",
    passdate: "2025-02-02",
    age: ranAge(),
    gisa: true,
  },
  {
    name: "E7E니",
    feature: "아재개긍",
    passdate: "",
    age: ranAge() + 20,
    gisa: false,
  },
];

// Just For Test용 추가 데이터 생성
Array.from({ length: 108 }).forEach((_, i) => {
  rowData.push({
    name: ranName(),
    feature: ranFeature(),
    passdate: ranDate(),
    age: ranAge() + 20,
    gisa: i % (i + i) ? true : false,
  });
});

const colDefs = [
  {
    field: "name",
    headerName: "이름",
    flex: 2,
    valueFormatter: (p) => {
      // console.log("체킁2:", p); // 누느로 확인하게 뽀인또
      return `${ranEmoji()} ${p.data.name}`;
    },
  },
  {
    field: "feature",
    headerName: "특징",
    flex: 1,
  },
  {
    field: "passdate",
    headerName: "합격일",
    flex: 2,
  },
  {
    field: "age",
    headerName: "나이",
    flex: 1,
  },
  {
    field: "gisa",
    headerName: "기사",
    flex: 1,
  },
];

const dummy = { rowData, colDefs };
export default dummy;

일부러 export(수출) 형태도 쪼메 고쳐보았당.(잘 아는가? 확인용!)

 

이제 GridExam.jsx를 data.js의 더미데이터와 설정을 쓰도록 다시 수정하장.

GridExam.jsx

/* eslint-disable no-unused-vars */
import { AllCommunityModule, ModuleRegistry } from "ag-grid-community";
import { AgGridReact } from "ag-grid-react";
import dummy from "./dummy/data";
import { useState } from "react";
ModuleRegistry.registerModules([AllCommunityModule]);

function GridExam() {
  const [rowData, setRowData] = useState(dummy.rowData);
  const [colDefs, setColDefs] = useState(dummy.colDefs);

  return (
    <div style={{ height: 500 }}>
      <AgGridReact rowData={rowData} columnDefs={colDefs} />
    </div>
  );
}

export default GridExam;

 

아래와 같은 예쁜 결과가 나오지 않으면 아니 되지 않은 거시 않는 게 아닌 게 맞을까?

일부러 데이터를 많이 넣었는데, 그건 Ag-Grid에서 지원하는 페이지 나누기 기능을 넣기 위해서당.

그렇당. 리스트에 페이지가 없다면  무한 스크롤이라도 있어야 하지 않겠는강?

 

아래 2줄의 코드 추가만으로 간단히 페이지 나누기가 자동으로 적용된당

pagination={true}       
paginationAutoPageSize={true}

 

적용시켜 보장.

GridExam.jsx

/* eslint-disable no-unused-vars */
import { AllCommunityModule, ModuleRegistry } from "ag-grid-community";
import { AgGridReact } from "ag-grid-react";
import dummy from "./dummy/data";
import { useState } from "react";
ModuleRegistry.registerModules([AllCommunityModule]);

function GridExam() {
  const [rowData, setRowData] = useState(dummy.rowData);
  const [colDefs, setColDefs] = useState(dummy.colDefs);

  return (
    <div style={{ height: 500 }}>
      <AgGridReact
        /* 페이지 나누기 적용 시작 */
        pagination={true}
        paginationAutoPageSize={true}
        /* 페이지 나누기 적용 끝 */
        rowData={rowData}
        columnDefs={colDefs}
      />
    </div>
  );
}

export default GridExam;

 

결과 화면 아래에 아래모양이 보일기당.

여기까지 잘 따라왔다면 훌륭하당. 칭찬 200번이당.

아직 할게 많지만... 역시 글로 쓰는 건 많이 많이 힘들당. 

물론 말도 많이하면  지치고, 또 지친당. 말 하면서 잠자는 초능력도 생긴당.

 

Ag-Grid에서 제공하는 테마가 몇개 있는데, vscode에서 

아래 그림처럼 ag-grid-community에서 import 하는 라인에 th라고 쓰면

자동으로 지원되는 테마를 알 수 있는데 , 디폴트는 themeQuartz

그냥 한번씩 바꿔 보장.

 

아래 처럼 바꿔볼 수 있겠당.

<AgGridReact
        theme={themeMaterial}
.... 생략
/>

 

좀 더 멋진 방법은 아래 링크에 가면 Ag-Grid 테마빌더를 제공한당.

https://www.ag-grid.com/theme-builder/

 

AG Grid Theme Builder

Easily build and customise themes for AG Grid with our interactive tool. Use our templates or create your own style from scratch. Export styles to AG Grid compatible themes.

www.ag-grid.com

직관적으로 만들어졌기 때문에 보는 순간 오해는 있어도 대략 알게 될꺼이당. 난 오해했당.

마구 고르고 선택한 다음, 화면 왼쪽 아래 그림 처럼 있는 use Theme 버튼을 세게 누른당.

그럼 Download 할거냥, Copy할거냥 버튼 2개가 보일기당.

Copy 버튼을 누르고 아래 처럼 붙여 넣었당.

 

GridExam.jsx

/* eslint-disable no-unused-vars */
import { AllCommunityModule, ModuleRegistry } from "ag-grid-community";
import { AgGridReact } from "ag-grid-react";
import dummy from "./dummy/data";
import { useState } from "react";
import { iconSetAlpine, themeQuartz } from "ag-grid-community";

ModuleRegistry.registerModules([AllCommunityModule]);

const myTheme = themeQuartz.withPart(iconSetAlpine).withParams({
  accentColor: "#0086F4",
  backgroundColor: "#F1EDE1",
  borderColor: "#98968F",
  borderRadius: 0,
  browserColorScheme: "light",
  chromeBackgroundColor: {
    ref: "backgroundColor",
  },
  fontFamily: {
    googleFont: "Pixelify Sans",
  },
  fontSize: 15,
  foregroundColor: "#605E57",
  headerBackgroundColor: "#E4DAD1",
  headerFontSize: 15,
  headerFontWeight: 700,
  headerTextColor: "#3C3A35",
  rowVerticalPaddingScale: 1.2,
  spacing: 5,
  wrapperBorderRadius: 0,
});

function GridExam() {
  const [rowData, setRowData] = useState(dummy.rowData);
  const [colDefs, setColDefs] = useState(dummy.colDefs);

  return (
    <div style={{ height: 500 }}>
      <AgGridReact
        theme={myTheme}
        pagination={true}
        paginationPageSize={10}
        paginationPageSizeSelector={[5, 10, 15, 20]}
        rowData={rowData}
        columnDefs={colDefs}
      />
    </div>
  );
}

export default GridExam;

 

한가지 더 눈에 넣고 싶은 코드가  귀에 들릴거당. 아래 코드당.

pagination={true}
paginationPageSize={10}
paginationPageSizeSelector={[5, 10, 15, 20]}

아까는 부모사이즈에 들어갈 내용만큼만 자동으로 적용했다면 

이번에 수동으로 페이지당 보여줄 갯수를 세팅하고 말았당.

결국 결과는 아래에 다다르고 말았당. 내꺼당!~~ ㅋㅋ

 

아무래도 추가적인 내용(Cell Render, Custom Cell, 중요 이벤트등은 다음글에서 담아보도록 하장

 


투명한 유리 구슬은 결코 약하지 않다고!

여자친구(GFRIEND)가 오래전에 노래했다.

 

꾸믈 꾼다를 난 착각한다로 해석한다.

착각한다를 난 오해한다로 해석한다.

 

오늘 난 꾸믈 꾸지 않을게당.

꾸믈 거릴 시간이 준비 되었당.

 

꾸믈 거릴 시간에 꾸믈 꾸는 난

그렇게 쉽게 꾸믈 꾸믈 꾸믈 이루고 말거당.

 

꾸믈 꾸믈 리듬감이 당신에게 없다면

당신은 꾸믈 꾸믈을 꾸믈데더라도 해석불가당.

 

인생은 꾸믈 꾸믈만 알면 다 아는 거당.

아 콩꼬믈 꾸믈 꼬믈 꾸믈 사 고푸당.

 

 

https://www.youtube.com/watch?v=GU7icQFVzHo

 

관련글 더보기