react-window:如何使用实际的表格标签

问题描述

我想使用语义 HTML 标签(而不是使用 div)来创建带有 react-window 的表格。

问题在于 List (FixedSizedList) 创建了两个包装器。一个被称为 outerElementType 并且也是 FixedSizedList 的道具,认值为 {{1} }.这意味着我无法创建正确的表结构,并且所有 div 最终都在第一列中。看起来这两个都不能省略。 我该如何解决这个问题?

当前代码

td

解决方法

对此的一种可能解决方案是将整个表格包含在列表中。为此,我们可以使用 react-window 中 sticky-header example 的修改版本。

您可以在此 CodeSandbox 中查看工作示例:https://codesandbox.io/s/wild-dust-jtf42?file=/src/index.js

我们需要两个简单的元素来呈现 StickyRowRow 元素。您可以在此处添加 td 元素。

const Row = ({ index,style }) => (
  <tr className="row" style={style}>
    Row {index}
  </tr>
);

const StickyRow = ({ index,style }) => (
  <tr className="sticky" style={style}>
    <th>Sticky Row {index}</th>
  </tr>
);

我们将 FixedSizeList 包装在包含粘性行的上下文中。在这种情况下,只有第一行是粘性的。

const StickyList = ({ children,stickyIndices,...rest }) => (
  <StickyListContext.Provider value={{ ItemRenderer: children,stickyIndices }}>
    <List itemData={{ ItemRenderer: children,stickyIndices }} {...rest}>
      {ItemWrapper}
    </List>
  </StickyListContext.Provider>
);

ItemWrapper 使用在主渲染函数中传递的方法(即 {Row})仅渲染非粘性行。这负责呈现表格数据。

const ItemWrapper = ({ data,index,style }) => {
  const { ItemRenderer,stickyIndices } = data;
  if (stickyIndices && stickyIndices.includes(index)) {
    return null;
  }
  return <ItemRenderer index={index} style={style} />;
};

为了呈现表格标题,我们需要一个自定义的innerElementType。

const innerElementType = forwardRef(({ children,...rest },ref) => (
  <StickyListContext.Consumer>
    {({ stickyIndices }) => (
      <table ref={ref} {...rest}>
        {stickyIndices.map(index => (
          <StickyRow
            index={index}
            key={index}
            style={{ top: index * 35,left: 0,width: "100%",height: 35 }}
          />
        ))}

        <tbody>
          {children}
        </tbody>
      </table>
    )}
  </StickyListContext.Consumer>
));

由于上下文,该元素知道粘性索引。并呈现标题和正文。

如果满足您的需要,可以进一步简化此代码。