React-window: htmlテヌブル芁玠の䜿甚

䜜成日 2018幎09月21日  Â·  34コメント  Â·  ゜ヌス: bvaughn/react-window

これをテヌブルで䜿甚する䟋はありたすか 私はそれを機胜させようずしおいたすが、それが機胜しないか、䜕か非垞に間違ったこずをしおいるのではないかず匷く疑っおいたす。
outerTagNameを "table"に、innerTagNameを "tbody"に蚭定したしたが、スクロヌルできたせん。

これが私のコヌドですが、それが圹立぀かどうかはわかりたせんアむテムはオブゞェクトのリストです

 <List
            outerRef={this._list}
            outerTagName="table"
            innerTagName="tbody"
            height={300}
            itemData={items}
            itemSize={() => 30}
            itemCount={items.length}
            itemKey={item => item.uniqueId}>
            {({index, style, data}) => {
              return (
                <tr style={style} key={index}>
                  <td>Item {index}</td>
                </tr>
              );
            }}
          </List>
💬 question

最も参考になるコメント

@pupudu私はあなたのオヌプン゜ヌスの努力を

非垞に小さなコヌドず倚くの創造性でこれを実珟するこずができたこずがわかりたした。 コヌドは非垞に単玔なので、誰でもコピヌ/貌り付けしお奜みに合わせお拡匵できたす。 @bvaughnは、方法を理解した埌、必芁に応じおラむブラリに远加するのは非垞に簡単ですが、方法を知っおいる堎合はオヌバヌラむドするのも非垞に簡単です。

それの䞍足

  • レンダリング埌の最初の行の「トップ」スタむルをキャプチャしたす
  • その倀をReact.Contextに保存しお、枡せるようにしたす
  • 行自䜓ではなく、移動されるテヌブルコンポヌネントに倀を適甚したす
  • ヘッダヌやフッタヌなどのスロットを远加したす。
  • ラむブラリの人間工孊では物事をきちんず枡すこずができないため、React.Contextはコンポヌネント間のコミュニケヌションを克服するためのヒヌロヌです。

䜜業コヌドサンドボックス https 

参照甚コヌド

import React from 'react'
import { useState, useRef, useContext } from 'react'
import { FixedSizeList, FixedSizeListProps } from 'react-window'
import { render } from 'react-dom'

/** Context for cross component communication */
const VirtualTableContext = React.createContext<{
  top: number
  setTop: (top: number) => void
  header: React.ReactNode
  footer: React.ReactNode
}>({
  top: 0,
  setTop: (value: number) => {},
  header: <></>,
  footer: <></>,
})

/** The virtual table. It basically accepts all of the same params as the original FixedSizeList.*/
function VirtualTable({
  row,
  header,
  footer,
  ...rest
}: {
  header?: React.ReactNode
  footer?: React.ReactNode
  row: FixedSizeListProps['children']
} & Omit<FixedSizeListProps, 'children' | 'innerElementType'>) {
  const listRef = useRef<FixedSizeList | null>()
  const [top, setTop] = useState(0)

  return (
    <VirtualTableContext.Provider value={{ top, setTop, header, footer }}>
      <FixedSizeList
        {...rest}
        innerElementType={Inner}
        onItemsRendered={props => {
          const style =
            listRef.current &&
            // @ts-ignore private method access
            listRef.current._getItemStyle(props.overscanStartIndex)
          setTop((style && style.top) || 0)

          // Call the original callback
          rest.onItemsRendered && rest.onItemsRendered(props)
        }}
        ref={el => (listRef.current = el)}
      >
        {row}
      </FixedSizeList>
    </VirtualTableContext.Provider>
  )
}

/** The Row component. This should be a table row, and noted that we don't use the style that regular `react-window` examples pass in.*/
function Row({ index }: { index: number }) {
  return (
    <tr>
      {/** Make sure your table rows are the same height as what you passed into the list... */}
      <td style={{ height: '36px' }}>Row {index}</td>
      <td>Col 2</td>
      <td>Col 3</td>
      <td>Col 4</td>
    </tr>
  )
}

/**
 * The Inner component of the virtual list. This is the "Magic".
 * Capture what would have been the top elements position and apply it to the table.
 * Other than that, render an optional header and footer.
 **/
const Inner = React.forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
  function Inner({ children, ...rest }, ref) {
    const { header, footer, top } = useContext(VirtualTableContext)
    return (
      <div {...rest} ref={ref}>
        <table style={{ top, position: 'absolute', width: '100%' }}>
          {header}
          <tbody>{children}</tbody>
          {footer}
        </table>
      </div>
    )
  }
)

/**
 * Render Our Example
 **/
render(
  <VirtualTable
    height={300}
    width="100%"
    itemCount={1000}
    itemSize={36}
    header={
      <thead>
        <tr>
          <th>Index</th>
          <th>Header 2</th>
          <th>Header 3</th>
          <th>Header 4</th>
        </tr>
      </thead>
    }
    row={Row}
    footer={
      <tfoot>
        <tr>
          <td>Footer 1</td>
          <td>Footer 2</td>
          <td>Footer 3</td>
          <td>Footer 4</td>
        </tr>
      </tfoot>
    }
  />,
  document.querySelector('main')
)

党おのコメント34件

これが実際に機胜するずは思わない。 私の知る限り、 HTMLTableElementは、りィンドりコンポヌネントが必芁ずするようなオヌバヌフロヌを実際にはサポヌトしおいたせん。 スタむルをdisplay: block倉曎するこずはできたすが、それでも正しく機胜するずは思いたせん。 これが䟋です。

なぜテヌブルが必芁なのですか むンラむンブロックたたはフレックスレむアりトで同じ列レむアりトを実珟できるず思いたす。

远加事項のカップル

  • requireパラメヌタwidthからList指定しおいたせん
  • 行にkeyを远加する必芁はありたせん
  • itemSizeは、 () => 30ではなく30にするこずができたすパフォヌマンスはわずかに向䞊したす

早速のお返事ありがずうございたす。
divぞの曞き換えに぀いおはすでに説明したしたが、これは既存のかなり倧きなコンポヌネント甚であるため、曞き換えを開始する前に確認したかっただけです。 rc-tableに぀いお他にもコメントがあったので、うたくいくはずだず思いたした。
ずにかく、曞き盎しを気にしないでください、それは私が思う䟡倀があるはずです。

行にキヌがないキヌに぀いおReactの譊告が衚瀺されたした。これは、itemKeyを蚭定しおいるこずを考えるず混乱を招き、そこで䜕が起こっおいるのかわかりたせん。

ありがずう

゚むナル

2018幎9月21日には、午前16時52分で、ブラむアン・ノォヌンの[email protected]は曞きたした

これが実際に機胜するずは思わない。 私の知る限り、HTMLTableElementは、りィンドりコンポヌネントが必芁ずするようなオヌバヌフロヌを実際にはサポヌトしおいたせん。 衚瀺するスタむルを倉曎するこずもできたすブロックですが、それでも正しく機胜するずは思いたせん。

なぜテヌブルが必芁なのですか むンラむンブロックたたはフレックスレむアりトで同じ列レむアりトを実珟できるず思いたす。

远加事項のカップル

リストに必須パラメヌタヌ幅を指定しおいたせん
行にキヌを远加する必芁はありたせん
itemSizeは、=> 30ではなく30にするこずができたすパフォヌマンスがわずかに向䞊したす
—
スレッドを䜜成したため、これを受け取っおいたす。
このメヌルに盎接返信するか、GitHubで衚瀺するか、スレッドをミュヌトしおください。

行にキヌがないキヌに぀いおReactの譊告が衚瀺されたした。これは、itemKeyを蚭定しおいるこずを考えるず混乱を招き、そこで䜕が起こっおいるのかわかりたせん。

これは予期されおいたせん。 コヌドサンドボックスを介しお再珟ケヌスを私ず共有できたすか

ああ、ごめんなさい。 itemKey関数が䞀郚のアむテムに察しおundefinedを返した堎合にのみ、これが予想されるこずを远加する必芁がありたす。その堎合、その関数を修正する必芁がありたす。

@bvaughnオヌバヌフロヌサポヌトが制限芁因であるこずに具䜓的なこずは䜕も芋぀かりたせん。 䞍思議なこずに、それが䜕であるか知りたいのですが。 確かに、䞡方のコア機胜をサポヌトするのは面倒かもしれたせんが、珟時点では、基本リスト芁玠だけが実装者の遞択から倖れおいるように芋えたす。 私自身ず、固定ヘッダヌシナリオでreact-windowを䜿甚しおいる可胜性のある人なら誰でも、テヌブルレむアりトに組み蟌たれた固有の衚圢匏のサポヌトを取埗するずよいでしょう。 displayの䜿甚tableは「いくらかの」開発オヌバヌヘッドを必芁ずし、偶然にテヌブルを䜿甚しお構築される可胜性のある呚囲のアプリケヌション向けの1回限りのレむアりトです。 私はい぀でもcssを介しおオヌバヌフロヌや他のプロパティを埮調敎するこずができたしたずにかく珟圚の実装でそれを行っおいたす。 elementTypeプロップは問題倖ですか

@bvaughnオヌバヌフロヌサポヌトが制限芁因であるこずに具䜓的なこずは䜕も芋぀かりたせん。

おそらく私は最高の蚀い回しを䜿甚しおいたせんでしたが、リンクしたサンドボックス rrn61wkzwm を芋るず、予期しない動䜜が芋られたす。

これはHTMLだけの別の䟋です lx65871p69

HTMLSelectElement  <tbody> は、 heightやoverflowなどのスタむルを無芖するため、りィンドり凊理には䜿甚できたせん。 衚瀺モヌド display: block を倉曎するこずでこれを「修正」できたすが、列のサむズ倉曎動䜜が損なわれるため、 HTMLTableElementを䜿甚する目的が無効になりたす。

サむズは列のコンテンツに䟝存するためナヌザヌがスクロヌルするず倉化するため、りィンドりのナヌスケヌスでは、そもそもその列のサむズ蚭定の動䜜は壊れおいたす。

しかし、珟時点では、基本リスト芁玠だけが実装者の遞択から倖れおいるように芋えたす... elementTypeプロップは問題倖ですか

本圓に必芁な堎合は 2j0z718mwy 、タグタむプをすでに指定できたすが、䜕が埗られるかはわかりたせん。

私自身ず、固定ヘッダヌシナリオでreact-windowを䜿甚しおいる可胜性のある人なら誰でも、テヌブルレむアりトに組み蟌たれた固有の衚圢匏のサポヌトを取埗するずよいでしょう。

HTMLTableElementを䜿甚するず、䞊蚘で説明した理由で問題が発生したす。 ヘッダヌが固定された衚圢匏/グリッドレむアりトが必芁な堎合は、通垞のリストコンポヌネントの1぀を䜿甚しおこれを実珟できたす pk78pvwnkx

なぜテヌブルが必芁なのですか むンラむンブロックたたはフレックスレむアりトで同じ列レむアりトを実珟できるず思いたす。

アクセシビリティのためにテヌブル構造が必芁なのかもしれたせんたずえば、非セマンティックdivず比范しおより良い画面読み䞊げ 私はここで掚枬しおいたす。

この堎合、CSSの衚瀺スタむルやテヌブル芁玠に固有の他のスタむルをオヌバヌラむドしたす。

箄9幎前に耇雑なテヌブルコンポヌネント䞊䞋に固定/固定された芋出し、耇雑なcolspan / rowspan構造、およびその背埌にある構造を説明するデヌタモデルを含むを構築した私の経隓圓時はReactも、アクセシビリティの懞念もありたせんでした仮想化がないこずを芚えおいる限りこのコンポヌネントを担圓した同僚は、適切なテヌブル芁玠にコンポヌネントを実装しようずし、レむアりトを特定の方法で動䜜させるのに苊劎し、から玔粋なJavaScriptでテヌブルレむアりトを実装するこずにしたした。絶察に配眮され、サむズ蚭定されたdiv。 その゜リュヌションは完党に機胜したした。奇劙なレむアりトゞャンプ、スムヌズなスクロヌル行ごず/列ごずではないなどはありたせん。

アクセシビリティのためにテヌブル構造が必芁なのかもしれたせんたずえば、非セマンティックdivず比范しおより良い画面読み䞊げ 私はここで掚枬しおいたす。

これにはAriaの圹割を䜿甚できたす😄

超培底、ありがずうございたす。 ある問題を解決しお他の問題を䜜成するだけのプロトタむプを詊すために、うさぎの穎を䞋っお行くのを助けおくれたした。

こんにちは
新しいスレッドを䜜成する代わりに、既存のスレッドを芋぀けようずしたした。 私は良い堎所にいるこずを願っおいたす...

FixedSizeGrid 2぀のセルをマヌゞする䞀皮の「colspan」を持぀方法はありたすか私のコンテキストではおそらくもっず意味がありたす
この質問は、ここで始たった別の議論に䟝存しおい

FixedSizeGridの2぀のセルをマヌゞするための䞀皮の「colspan」を持぀方法はありたすか私のコンテキストではおそらくもっず意味がありたす

いいえ。これはサポヌトされおいたせん。

@einarq @BlaineBradbury @sompylasarただ興味がある堎合は、テヌブルタグを䜿甚しおりィンドり凊理を行うこずができたした。 実際、react-windowをラップするラむブラリを䜜成するこずになりたした。 ここでラむブデモを芋るこずができたす https 

テヌブルタグが欲しかったのは、䞻にスタむリングのためでした。 通垞のhtmlテヌブルのスタむリングはtw-bootstrapを䜿甚するず非垞に簡単なので、りィンドりテヌブルでも同じこずをしたいず思いたした。

私はブラむアンにタグを付けお、この実装に぀いおどう思うか尋ねたくなりたす圌はhtmlテヌブルタグが機胜しないず蚀ったので。 しかし、圌はすでに私を十分に助けおくれたした。 だから私はあなたたちにそれを任せたす。

ありがずうございたした。

それは興味深いアプロヌチ@pupuduです。 ヘッダヌず行に別々の<table>タグを付けるこずでアクセシビリティの懞念があるかどうかはわかりたせんが、そうでない堎合は適切なアむデアです。

react-datasheetをreact-windowず䞀緒に䜿甚しようずしおいたすが、基本的には機胜したす。

function sheetRenderer(props) {
  const Row = ({ index, style }) => (
    React.cloneElement(props.children[index], { style })
  );
  return (
    <table className={props.className}>
        <tbody>
          <FixedSizeList
              height={150}
              itemCount={1000}
              itemSize={35}
              width={300}
          >
            {Row}
          </FixedSizeList>
        </tbody>
    </table>
  )
}

export default function EntityTable(props: IEntityTableProps) {
  const initialGrid = useMemo(() => {
    return getTableGridFromCSV(props.entityListCSV);
  }, [props.entityListCSV]);
  const [modifiedGrid, updateModifiedGrid] = useImmer(initialGrid);
  return (
    <ReactDataSheet
      data={modifiedGrid}
      sheetRenderer={sheetRenderer}
      valueRenderer={cell => cell.value}
      onCellsChanged={changes => {
        updateModifiedGrid(draft => {
          changes.forEach(({ cell, row, col, value }) => {
            draft[row][col].value = value || '';
          });
        });
      }}
    />
  );
}

function getTableGridFromCSV(csv: string) {
  return csv.split('\n').map(row =>
    row.split(',').map((cell, index) => {
      if (index === 0) {
        return {
          value: cell,
          forceComponent: true,
          component: <button onClick={() => console.log(cell)}>{cell}</button>,
        };
      }
      if (index === 2) {
        return {
          value: cell,
        };
      }
      return {
        value: cell,
        component: <span>{cell}</span>,
      };
    }),
  );
}

レンダリングされたす。唯䞀の問題はWarning: validateDOMNesting(...): <tr> cannot appear as a child of <div>. index.js:1437 Warning: validateDOMNesting(...): <div> cannot appear as a child of <tbody>.

ねえ、私はReact-Tableでこれを詊しおいたすが、テヌブル芁玠の代わりにdivを䜿甚する必芁があるこずに気づきたした。 これに関する問題は、material / bootstrapのようなスタむリングラむブラリがこれらの芁玠に䟝存しおいるこずです。 したがっお、テヌブルスキヌマをテヌブル芁玠ではなくdivに倉曎するのははるかに手間がかかりたす。 テヌブル芁玠を䜿甚しお差分をずるこずは可胜ですか、それずも今すぐ独自のスタむルを䜜成する必芁がありたすか

@simkessyすでに気づいおいない限り、りィンドりテヌブルをチェックアりトする必芁がありたす。 htmlテヌブルタグを䜿甚できるため、既存のスタむルを再利甚できたす。 ただし、テヌブルはreact-tableほど高床ではないこずを認める必芁がありたす。
https://window-table.netlify.com/

@pupudu私はあなたのオヌプン゜ヌスの努力を

非垞に小さなコヌドず倚くの創造性でこれを実珟するこずができたこずがわかりたした。 コヌドは非垞に単玔なので、誰でもコピヌ/貌り付けしお奜みに合わせお拡匵できたす。 @bvaughnは、方法を理解した埌、必芁に応じおラむブラリに远加するのは非垞に簡単ですが、方法を知っおいる堎合はオヌバヌラむドするのも非垞に簡単です。

それの䞍足

  • レンダリング埌の最初の行の「トップ」スタむルをキャプチャしたす
  • その倀をReact.Contextに保存しお、枡せるようにしたす
  • 行自䜓ではなく、移動されるテヌブルコンポヌネントに倀を適甚したす
  • ヘッダヌやフッタヌなどのスロットを远加したす。
  • ラむブラリの人間工孊では物事をきちんず枡すこずができないため、React.Contextはコンポヌネント間のコミュニケヌションを克服するためのヒヌロヌです。

䜜業コヌドサンドボックス https 

参照甚コヌド

import React from 'react'
import { useState, useRef, useContext } from 'react'
import { FixedSizeList, FixedSizeListProps } from 'react-window'
import { render } from 'react-dom'

/** Context for cross component communication */
const VirtualTableContext = React.createContext<{
  top: number
  setTop: (top: number) => void
  header: React.ReactNode
  footer: React.ReactNode
}>({
  top: 0,
  setTop: (value: number) => {},
  header: <></>,
  footer: <></>,
})

/** The virtual table. It basically accepts all of the same params as the original FixedSizeList.*/
function VirtualTable({
  row,
  header,
  footer,
  ...rest
}: {
  header?: React.ReactNode
  footer?: React.ReactNode
  row: FixedSizeListProps['children']
} & Omit<FixedSizeListProps, 'children' | 'innerElementType'>) {
  const listRef = useRef<FixedSizeList | null>()
  const [top, setTop] = useState(0)

  return (
    <VirtualTableContext.Provider value={{ top, setTop, header, footer }}>
      <FixedSizeList
        {...rest}
        innerElementType={Inner}
        onItemsRendered={props => {
          const style =
            listRef.current &&
            // @ts-ignore private method access
            listRef.current._getItemStyle(props.overscanStartIndex)
          setTop((style && style.top) || 0)

          // Call the original callback
          rest.onItemsRendered && rest.onItemsRendered(props)
        }}
        ref={el => (listRef.current = el)}
      >
        {row}
      </FixedSizeList>
    </VirtualTableContext.Provider>
  )
}

/** The Row component. This should be a table row, and noted that we don't use the style that regular `react-window` examples pass in.*/
function Row({ index }: { index: number }) {
  return (
    <tr>
      {/** Make sure your table rows are the same height as what you passed into the list... */}
      <td style={{ height: '36px' }}>Row {index}</td>
      <td>Col 2</td>
      <td>Col 3</td>
      <td>Col 4</td>
    </tr>
  )
}

/**
 * The Inner component of the virtual list. This is the "Magic".
 * Capture what would have been the top elements position and apply it to the table.
 * Other than that, render an optional header and footer.
 **/
const Inner = React.forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
  function Inner({ children, ...rest }, ref) {
    const { header, footer, top } = useContext(VirtualTableContext)
    return (
      <div {...rest} ref={ref}>
        <table style={{ top, position: 'absolute', width: '100%' }}>
          {header}
          <tbody>{children}</tbody>
          {footer}
        </table>
      </div>
    )
  }
)

/**
 * Render Our Example
 **/
render(
  <VirtualTable
    height={300}
    width="100%"
    itemCount={1000}
    itemSize={36}
    header={
      <thead>
        <tr>
          <th>Index</th>
          <th>Header 2</th>
          <th>Header 3</th>
          <th>Header 4</th>
        </tr>
      </thead>
    }
    row={Row}
    footer={
      <tfoot>
        <tr>
          <td>Footer 1</td>
          <td>Footer 2</td>
          <td>Footer 3</td>
          <td>Footer 4</td>
        </tr>
      </tfoot>
    }
  />,
  document.querySelector('main')
)

@jamesmfriedmanアプロヌチが倧奜きです。 これを達成するためにコンテキストを䜿甚するための本圓に興味深いアむデア。 ヘッダヌ甚ずボディ甚の2぀をレンダリングする私のアプロヌチずは異なり、テヌブルを1぀だけレンダリングするずいう事実が気に入っおいたす。 これは、りィンドりテヌブルのナヌザヌに倚くの混乱を匕き起こしたしたそれが来るのを芋おいたせんでした。

よろしければ、これらのアむデアをりィンドりテヌブルで䜿甚しおみたす。 最倧の課題は、コンテンツに基づいお行のサむズを自動化する方法を芋぀けるこずだず思いたすこれは、少なくずもwindo-tableの最倧の課題でした。

非垞に有望に芋える@jamesmfriedman 。 @bvaughnこのアプロヌチに぀いお䜕か懞念はありたすか

@jamesmfriedmanヘッダヌがコンテンツず䞀緒に䞊にスクロヌルするようです。 べた぀くこずはできたすか

実際には可胜であり、この実装に固有のものではありたせん。 HTMLテヌブル芁玠を䜿甚しおスティッキヌヘッダヌをグヌグルで怜玢するだけです。 これを行う方法は、実際にはTH芁玠の䜍眮を固定するこずであるず挠然ず思い出したす。

スティッキヌヘッダの👍それは倚くがここに@marink助けたあなた䟋えば@jamesmfriedmanおかげでたくさんは䞀䟋ですhttps://codesandbox.io/s/react-window-with-table-elements-jj70eあなたが远加する必芁がstyle={{ position: 'sticky', top: 0 }}>からthタグ

@jamesmfriedman䟋をありがずう。 私はそれを䜿甚するこずを怜蚎する぀もりです。 しかし、 topを再蚈算しおテヌブル芁玠に絶察䜍眮を蚭定する代わりに、

したがっお、79行目は<table style={{ top: 0, position: 'sticky', width: '100%' }}>

これにより、䞀番䞋にいるずきにスクロヌルを続ける堎合のスクロヌルの問題も修正されたす。

HTMLテヌブルを䜿甚するもう1぀の理由は、IE11をサポヌトするこずです。 FixedSizeListを䜿甚しお、CSSグリッドでスタむルを蚭定しおいたす。 ただし、レスポンシブ列やサむズの異なる列などの他の機胜を远加し、すべおをIE11ず連携させる必芁がある堎合は、倧量のコヌドが必芁になりたす。 HTMLテヌブルはデフォルトでコヌドなしで機胜したす。

IE11はもうサポヌトすべきものではありたせん:)

すべおのFE開発者は、IE11の死を望んでいたす。 しかし、残念ながら、私たちが想像するこずさえできない理由のために行動を起こすこずができない、それに固執しおいる䌁業/人々がいたす。 うたくいけば、それはほんの数幎先のこずです。 それたでは、奜むず奜たざるずにかかわらず、IE11をサポヌトする必芁がありたす。

私にずっおも飲み蟌むのは難しい薬でした。

@ olafur164高速スクロヌルでスティッキヌヘッダヌが壊れないように修正しおございたす。 スムヌズに反察するように䞀床に1行ず぀スクロヌルするので、「スティッキヌ」な倖芳を維持する方法があるかどうか知っおいたすか

私の経隓をreact-virtualized  react-windowの問題ペヌゞでもず同じ問題が発生するmaterial-tableず呌ばれるいく぀かのマテリアルUIラむブラリ仮想化ずテヌブル芁玠の組み合わせで共有したしょう https  validateDOMNesting(...)譊告など、ただいく぀かの問題がありたす。

@jamesmfriedmanはあなたの䟋に感謝したす👍それは倧いに圹立ちたしたthタグにstyle={{ position: 'sticky', top: 0 }}>を远加する必芁がありたす

@JCofmanさん、CSS修正を詊したしたが、機胜したせん。 コヌドサンドボックスの䟋は次のずおりです-https//codesandbox.io/s/react-window-with-table-elements-forked-huti6file = / src / index.tsx514-542

2぀の問題がありたす-

  1. スタむルが蚭定されおいるにもかかわらず、ヘッダヌが䞊郚に貌り付いおいたせん。
  2. 䞊方向に倧きくスクロヌルしおいる間、ヘッダヌが点滅/ちら぀きたす。
    [再珟手順-50䞋にスクロヌルしおから、䞊に高速スクロヌルしおヘッダヌの動きを芳察したす]。

前もっお感謝したす 

@jamesmfriedmanアプロヌチが倧奜きです。 これを達成するためにコンテキストを䜿甚するための本圓に興味深いアむデア。 ヘッダヌ甚ずボディ甚の2぀をレンダリングする私のアプロヌチずは異なり、テヌブルを1぀だけレンダリングするずいう事実が気に入っおいたす。 これは、りィンドりテヌブルのナヌザヌに倚くの混乱を匕き起こしたしたそれが来るのを芋おいたせんでした。

よろしければ、これらのアむデアをりィンドりテヌブルで䜿甚しおみたす。 最倧の課題は、コンテンツに基づいお行のサむズを自動化する方法を芋぀けるこずだず思いたすこれは、少なくずもwindo-tableの最倧の課題でした。

行にdisplay: contentsを䜿甚しおdisplay: gridを䜿甚しおいるため、非垞によく䌌た解決策を芋぀けるこずになりたした。したがっお、基本的にtable > tr芁玠の制玄に埓いたす。

context + refsを䜿甚しお内郚メ゜ッドを呌び出したしたが、最初の子のstyle.top倀を怜玢するこずで同じこずができるため、これはたったく䞍芁です。

const Inner = React.forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
  function Inner({ children, ...rest }, ref) {
    const { header, footer } = useContext(VirtualTableContext)
    const {style} = children[0].props;
    return (
      <div {...rest} ref={ref}>
        <table style={style}>
          {header}
          <tbody>{children}</tbody>
          {footer}
        </table>
      </div>
    )
  }
)

スタむルプロップは、各行に察しおcreateElementを実行するずきにラむブラリによっお提䟛され、特定のRowコンポヌネントはstyleをtrに割り圓おないため、そうではありたせん。どちらかを枡したす。

最近、こんなこずを考えおいたした。 cssカスタムプロパティを介しお疑䌌芁玠埌/前を䜿甚しおパディングでテヌブル本䜓党䜓を移動するずどうなりたすか🀔

反応仮想を䜿甚する䟋では、 https//codesandbox.io/s/poc-react-virtual-table-jyz0mになり

必芁なUXを実珟するためにテヌブルが絶察に必芁でしたが、 react-windowで機胜させるための回避策に満足できたせん

結局、私は自分で仮想化ロゞックをフックに抜出し、2぀のテヌブルを䜿甚しお実装したした。1぀はヘッダヌ甚で、もう1぀はコンテンツ甚です。 私のアプロヌチの違いは、2番目のテヌブルにはただマヌクアップにヘッダヌがありたすが、アクセス可胜なたたであるように芖芚的に非衚瀺になっおいるのに察し、最初のテヌブルのヘッダヌは目の芋えるナヌザヌのためだけにあり、䜍眮的に固定されおいたした。コヌドは倧幅に単玔化されたした。

誰かがそれを詊したい堎合に備えお、それを捚おるだけです。

@piecykこれは玠晎らしいもので、virtuosoの実装方法ず非垞によく䌌おいたす https  //virtuoso.dev/grouped-by-first-letter/

コンテナ党䜓をabsolute / topで配眮するこずはパフォヌマンスが高いこずを远加する必芁がありたすが、Chromeでパフォヌマンス監査を実行するず、FPSに圱響を䞎える可胜性のあるCLSの問題が発生したす。 圱響は目立たないず思いたす。この䟋では、 https 

私はこれを自分で詊みお、近いうちに違いを枬定したす。

@pupudu私はあなたのオヌプン゜ヌスの努力を

非垞に小さなコヌドず倚くの創造性でこれを実珟するこずができたこずがわかりたした。 コヌドは非垞に単玔なので、誰でもコピヌ/貌り付けしお奜みに合わせお拡匵できたす。 @bvaughnは、方法を理解した埌、必芁に応じおラむブラリに远加するのは非垞に簡単ですが、方法を知っおいる堎合はオヌバヌラむドするのも非垞に簡単です。

_それの䞍足_

  • レンダリング埌の最初の行の「トップ」スタむルをキャプチャしたす
  • その倀をReact.Contextに保存しお、枡せるようにしたす
  • 行自䜓ではなく、移動されるテヌブルコンポヌネントに倀を適甚したす
  • ヘッダヌやフッタヌなどのスロットを远加したす。
  • ラむブラリの人間工孊では物事をきちんず枡すこずができないため、React.Contextはコンポヌネント間のコミュニケヌションを克服するためのヒヌロヌです。

䜜業コヌドサンドボックス https 

参照甚コヌド

import React from 'react'
import { useState, useRef, useContext } from 'react'
import { FixedSizeList, FixedSizeListProps } from 'react-window'
import { render } from 'react-dom'

/** Context for cross component communication */
const VirtualTableContext = React.createContext<{
  top: number
  setTop: (top: number) => void
  header: React.ReactNode
  footer: React.ReactNode
}>({
  top: 0,
  setTop: (value: number) => {},
  header: <></>,
  footer: <></>,
})

/** The virtual table. It basically accepts all of the same params as the original FixedSizeList.*/
function VirtualTable({
  row,
  header,
  footer,
  ...rest
}: {
  header?: React.ReactNode
  footer?: React.ReactNode
  row: FixedSizeListProps['children']
} & Omit<FixedSizeListProps, 'children' | 'innerElementType'>) {
  const listRef = useRef<FixedSizeList | null>()
  const [top, setTop] = useState(0)

  return (
    <VirtualTableContext.Provider value={{ top, setTop, header, footer }}>
      <FixedSizeList
        {...rest}
        innerElementType={Inner}
        onItemsRendered={props => {
          const style =
            listRef.current &&
            // @ts-ignore private method access
            listRef.current._getItemStyle(props.overscanStartIndex)
          setTop((style && style.top) || 0)

          // Call the original callback
          rest.onItemsRendered && rest.onItemsRendered(props)
        }}
        ref={el => (listRef.current = el)}
      >
        {row}
      </FixedSizeList>
    </VirtualTableContext.Provider>
  )
}

/** The Row component. This should be a table row, and noted that we don't use the style that regular `react-window` examples pass in.*/
function Row({ index }: { index: number }) {
  return (
    <tr>
      {/** Make sure your table rows are the same height as what you passed into the list... */}
      <td style={{ height: '36px' }}>Row {index}</td>
      <td>Col 2</td>
      <td>Col 3</td>
      <td>Col 4</td>
    </tr>
  )
}

/**
 * The Inner component of the virtual list. This is the "Magic".
 * Capture what would have been the top elements position and apply it to the table.
 * Other than that, render an optional header and footer.
 **/
const Inner = React.forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
  function Inner({ children, ...rest }, ref) {
    const { header, footer, top } = useContext(VirtualTableContext)
    return (
      <div {...rest} ref={ref}>
        <table style={{ top, position: 'absolute', width: '100%' }}>
          {header}
          <tbody>{children}</tbody>
          {footer}
        </table>
      </div>
    )
  }
)

/**
 * Render Our Example
 **/
render(
  <VirtualTable
    height={300}
    width="100%"
    itemCount={1000}
    itemSize={36}
    header={
      <thead>
        <tr>
          <th>Index</th>
          <th>Header 2</th>
          <th>Header 3</th>
          <th>Header 4</th>
        </tr>
      </thead>
    }
    row={Row}
    footer={
      <tfoot>
        <tr>
          <td>Footer 1</td>
          <td>Footer 2</td>
          <td>Footer 3</td>
          <td>Footer 4</td>
        </tr>
      </tfoot>
    }
  />,
  document.querySelector('main')
)

これをありがずう、誰かがこれをInfiniteLoaderコンポヌネントで成功しお䜿甚しようずしたしたか...私はそれを蹎っおみたしたが、内偎の「ラッパヌ」に問題がありたす。無限ロヌダヌが予期しない小道具をinnerElementTypeに枡しおいるためだず思いたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡