@toast-ui/react-grid (toast grid, tui grid, 토스트그리드) 사용시 data.some is not a function (data.map is not a function)… 등의 에러가 발생했던 경험.

By | 10월 11, 2022

문제상황

  • toast grid 의 특정 셀을 클릭하여 modal을 띄우는 과정에서 아래와 같은 스크립트 에러 발생

    react-dom.development.js:26923 Uncaught TypeError: data.some is not a function
    at Object.createData (item.js:267:4)
    at Object.resetData (dropdown.js:314:7)
    at Grid2.dispatch (utils.js:69:8)
    at Grid2.resetData (utils.js:69:8)
    at toastui-react-grid.js:1:4602
    at Array.forEach (<anonymous>)
    at c2.value (toastui-react-grid.js:1:4525)
    at checkShouldComponentUpdate (react-dom.development.js:14134:33)
    at updateClassInstance (react-dom.development.js:14698:62)
    at updateClassComponent (react-dom.development.js:19695:20)
  • 오류메시지의 data가 Grid Property의 data 속성을 말하는 것 같아서, data object에 빈 함수 some을 추가해 줬더니, 이제 data.some 이 아니라 data.map 에서 오류 발생

  • 실험을 하다 보니 모달을 띄우는 것 뿐만 아니라, Grid가 들어 있는 페이지 컴포넌트의 어떤 useState에 set을 해도 해당 문제가 발생했다. (Modal의 경우 setOpen(true)를 호출하여 페이지 리렌더링을 유발한 것이 문제였던 듯)

  • 기존 코드에서 Grid 프로퍼티들을 Grid 태그 내에 직접 기재하지 않고, FC 내에 javascript 객체로 생성하여 {...gridProps} 와 같은 형태로 사용하고 있었는데, 리렌더링 과정에서 data 내 fetcher 정의부 등에서 문제가 발생하는 것이 아닐까 하는 촉이 옴.

  • 그리드 프로퍼티 정의 객체를 useMemo() 처리하니 에러가 발생하지 않았다. 해결!! ㅠㅠ

  • 가독성을 위해서 Grid 프로퍼티들을 태그에 직접 기재하지 않고 javascript 객체로 빼 놓았던 것인데, 처음부터 그렇게 하지 않았다면 이런 시행착오를 겪지 않았을 지도 모른다. 흠..


이하 최종 형태

const grid1 = useRef<typeof Grid>(null);

// 그리드1 속성 정의 (useMemo 반드시 사용할 것)
const grid1Props: GridProps = useMemo(
() => ({
  // data: dataSource,
  data: {
    api: {
      readData: { url: `${API_BASE_URL}/sampleGridTest01`, method: 'POST', initParams: { param1: 'ABC', param2: 123 } },
      modifyData: { url: `${API_BASE_URL}/sampleGridTest01`, method: 'POST' },
      // createData: { url: `${API_BASE_URL}/v1/createMsg`, method: 'POST' },
      // updateData: { url: `${API_BASE_URL}/v1/updateMsg`, method: 'PUT' },
      // deleteData: { url: `${API_BASE_URL}/v1/deleteMsg`, method: 'DELETE' },
    },
      contentType: 'application/json',
      withCredentials: true, // 필수
      hideLoadingBar: false,
  },
  columnOptions: {
    minWidth: 150,
    resizable: true,
    frozenCount: 1,
  },
  columns: grid1Cols, // FC 밖에서 별도 정의
  rowHeight: 30,
  bodyHeight: 400,
  heightResizable: true,
  rowHeaders: ['rowNum', 'checkbox'],
  onClick: handleGridClick,
  // onSuccessResponse: (ev) => {}, // 이걸 사용하니 조회후 오류가 발생하면서 그리드 데이터 출력이 안됨. 그래서 그냥 onResponse를 활용하기로 함.
  onResponse: onRsp,
  contextMenu: null as any, // context menu를 사용하지 않기 위해 null 입력시 ts 에러가 발생하여 any 처리
}),
[],
);   

...

<Grid ref={grid1} {...grid1Props} />
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments