Framework/React

[React] react-virtuoso dynamic height ๋™์  ๋†’์ด ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ• (+ mui)

yuri lee 2024. 9. 2. 22:54
๋ฐ˜์‘ํ˜•

Intro

์•ˆ๋…•ํ•˜์„ธ์š”. ์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” react-virtuoso ์—์„œ ๋™์  ๋†’์ด๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ์ €๋Š” third-party mui tabler๊ณผ ๊ฒฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

 

My case

react-virtuoso mui table ์‚ฌ์šฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. height ๋ฅผ ์„ค์ •ํ•ด์ค„ ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ณ ์ •๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

export default function ReactVirtualizedTable() {
  return (
    <Paper style={{ height: 400, width: '100%' }}>
      <TableVirtuoso
        data={rows}
        components={VirtuosoTableComponents}
        fixedHeaderContent={fixedHeaderContent}
        itemContent={rowContent}
      />
    </Paper>
  );
}

 

์ œ ์ผ€์ด์Šค์˜ ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ rows ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๊ณ , ๊ทธ ๋ฐ์ดํ„ฐ๋“ค์€ ๊ฐ๊ฐ ๋†’์ด๊ฐ€ ๋‹ฌ๋ผ์„œ height๋ฅผ ๋™์ ์œผ๋กœ ์„ค์ •ํ•ด์ค˜์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ์š”? 

 

How to solve the problem

import React, { useMemo } from 'react';

const DynamicHeightVirtualizedTable  = ({ headers, rows, stickyHeader, realTime }) => {
    const ref = useRef(null);

  // ๊ฐ row ์˜ ๋†’์ด ์„ค์ •
  const rowHeight = 65;

  const dynamicHeight = useMemo(() => {
    if (!rows || rows.length === 0) return 222; // rows๊ฐ€ ์—†์„ ๋•Œ ์ตœ์†Œํ•œ์˜ row ๋†’์ด ์„ค์ •
    const calculatedHeight = 120 + (rows.length * rowHeight); // 120์˜ ๊ฒฝ์šฐ header ๋†’์ด์—ฌ์„œ ๋”ํ•ด์คŒ, ๊ฐ๊ฐ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋จ 

    // ์ €๋Š” min height๋ฅผ ์ง€์ •ํ•ด์ฃผ๊ณ  ์‹ถ์–ด์„œ ๋‹ค์Œ์˜ ๋กœ์ง์„ ํ™œ์šฉํ•จ
    return Math.min(calculatedHeight, 850);
  }, [rows]);

  {/* ...code omitted for brevity... */}

  return (
    <Paper
      style={{
        height: dynamicHeight,
        width: '100%',
        backgroundColor: 'transparent',
        overflowX: 'auto',
      }}
      ref={ref}
    >
      <TableVirtuoso
        data={rows}
        components={VirtuosoTableComponents}
        fixedHeaderContent={fixedHeaderContent}
        itemContent={rowContent}
      />

    </Paper>
  );
};

 

๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋จผ์ € ๋™์  ๋†’์ด๋กœ ์‚ฌ์šฉํ•  ๋ณ€์ˆ˜(dynamicHeight)๋ฅผ ์„ ์–ธํ•ด์ค๋‹ˆ๋‹ค. useRef๋ฅผ ํ™œ์šฉํ•ด์„œ ๋†’์ด๋ฅผ ๊ณ„์‚ฐํ•  ์ปดํฌ๋„ŒํŠธ์— ref ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค. 

 

์‚ฌ์šฉํ•˜๊ณ  ๊ณ„์‹œ๋Š” ์Šคํƒ€์ผ์— ๋”ฐ๋ผ row์˜ ๋†’์ด๊ฐ€ ๋‹ค๋ฅผํ…๋ฐ์š”, ์ €๋Š” 65px์ด์—ฌ์„œ ๊ธฐ๋ณธ ๋†’์ด๋ฅผ 65๋กœ ์„ค์ •ํ–ˆ๊ณ , ํ˜น์‹œ rows ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๊ฑฐ๋‚˜, length๊ฐ€ 0์ผ ๋•Œ๋ฅผ ๋ฐ๋น„ํ•˜์—ฌ ์ตœ์†Œ ๋†’์ด๋„ ๋”ฐ๋กœ ์„ค์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ดํ›„ rows.length ๋งŒํผ rowHeight๋ฅผ ๊ณฑํ•ด์ค๋‹ˆ๋‹ค. ์ €๋Š” header์˜ ๋†’์ด๊นŒ์ง€ ๊ณ ๋ คํ•˜์—ฌ 120px๋ฅผ ๋”ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ๋™์  ๋†’์ด๊ฐ€ rows๋งˆ๋‹ค ์ž˜ ๋™์ž‘ํ•˜๋Š”๋ฐ์š”, ์ €๋Š” ์•„๋ฌด๋ฆฌ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„๋„ ๋„ˆ๋ฌด ๊ธธ์–ด๋ณด์ด๋Š” ๊ฑด ์›ํ•˜์ง€ ์•Š์•„์„œ, ์ตœ์†Œํ•œ์˜ ๋†’์ด๋กœ 850px์„ ์„ค์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. 

 

ํ•ด๋‹น ๋ฐฉ๋ฒ• ํ™œ์šฉ ์‹œ react-virtuoso ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋™์  ๋†’์ด๋กœ๋„ ์„ค์ •์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 

 


https://virtuoso.dev/mui-table-virtual-scroll/

 

๋ฐ˜์‘ํ˜•