Framework/React

[React] react-virtuoso TableVirtuoso ๋นˆ๋ฐฐ์—ด์ผ ๋•Œ EmptyPlaceholder ์†์„ฑ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

yuri lee 2024. 9. 3. 22:04
๋ฐ˜์‘ํ˜•

Intro

์•ˆ๋…•ํ•˜์„ธ์š”. ์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” TableVirtuoso ์‚ฌ์šฉ ์ค‘ ๋ฐ์ดํ„ฐ๊ฐ€ ๋นˆ ๋ฐฐ์—ด์ผ ๋•Œ EmptyPlaceholder ์†์„ฑ์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

Example

ํ˜„์žฌ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ์ด ์ƒํƒœ์—์„œ dataList๊ฐ€ null์ด๊ฑฐ๋‚˜ ๋นˆ๋ฐฐ์—ด์ผ ๋•Œ ํŠน์ • ๋ฐ์ดํ„ฐ๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋Š” ํŠน์ • ํ…์ŠคํŠธ๋ฅผ ํ‘œ์‹œํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

const VirtuosoTableComponents = (totalColSpan: number): TableComponents<any> => ({
  Scroller: React.forwardRef<HTMLDivElement>((props, ref) => (
    <TableContainer {...props} ref={ref} />
  )),
  Table: (props) => (
    <Table {...props} sx={{ borderCollapse: 'separate', tableLayout: 'fixed' }} />
  ),
  TableHead: React.forwardRef<HTMLTableSectionElement>((props, ref) => (
    <TableHead {...props} ref={ref} />
  )),
  TableRow,
  TableBody: React.forwardRef<HTMLTableSectionElement>((props, ref) => (
    <TableBody {...props} ref={ref} />
  ))
});

const VirtualizedTable = <T extends TypeRES>({
  headers,
  rows,
}: Props<T>) => {
  const theme = useTheme();
  const [dataList, setDataList] = useState<T[]>(rows);

  useEffect(() => {
    setDataList(rows);
  }, [rows]);

  let totalColSpan = 1;

  headers?.forEach(header => {
    totalColSpan += header.subHeaders?.length ?? 1;
  });

  const memoizedVirtuosoTableComponents = useMemo(
    () => VirtuosoTableComponents(totalColSpan),
    [totalColSpan]
  );

  const fixedHeaderContent = () => {
    const filteredHeaders = headers?.filter(header => !header.hide);

    return (
      <>
       ...
      </>
    );
  };

  const rowContent = (_index: number, row: any) => {
    // Row content 
  };

  return (
    <Box style={{ height: 600, width: '100%', backgroundColor: 'transparent', overflowX: 'auto' }} >
      <TableVirtuoso
        data={dataList}
        components={memoizedVirtuosoTableComponents}
        fixedHeaderContent={fixedHeaderContent}
        itemContent={rowContent}
      />
    </Box>
  );
};

export default VirtualizedTable;

 

How to solve the problem

VirtuosoTableComponents ์ปดํฌ๋„ŒํŠธ ์„ ์–ธ ์‹œ EmptyPlaceholder ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ™œ์šฉํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. <TableBody> ํƒœ๊ทธ๋ถ€ํ„ฐ ํ™œ์šฉํ•˜์—ฌ ๋นˆ๋ฐฐ์—ด์ผ ๋•Œ ํ‘œ์‹œํ•˜๊ณ ์ž ํ•˜๋Š” ํ…์ŠคํŠธ ํ˜น์€ ์•„์ด์ฝ˜์„ ๋„ฃ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ €๋Š” colSpan ์†์„ฑ๋„ ์ถ”๊ฐ€๋กœ ์ „๋‹ฌํ•˜์—ฌ ํ…Œ์ด๋ธ”์˜ header์— ๋งž๊ฒŒ colSpan๋„ ์ ์šฉ๋˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

const VirtuosoTableComponents = (totalColSpan: number): TableComponents<any> => ({
  Scroller: React.forwardRef<HTMLDivElement>((props, ref) => (
    <TableContainer {...props} ref={ref} />
  )),
  Table: (props) => (
    <Table {...props} sx={{ borderCollapse: 'separate', tableLayout: 'fixed' }} />
  ),
  TableHead: React.forwardRef<HTMLTableSectionElement>((props, ref) => (
    <TableHead {...props} ref={ref} />
  )),
  TableRow,
  TableBody: React.forwardRef<HTMLTableSectionElement>((props, ref) => (
    <TableBody {...props} ref={ref} />
  )),
  EmptyPlaceholder: React.forwardRef(() => {
    return (
      <TableBody>
        <TableRow>
          <TableCell align="center" colSpan={totalColSpan -1 }>
            <Typography>๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.</Typography>
          </TableCell>
        </TableRow>
      </TableBody>
    );
  }),
});

 

๋ฐ˜์‘ํ˜•