【问题标题】:react-window: How to use actual table tagsreact-window:如何使用实际的表格标签
【发布时间】:2021-05-01 06:13:14
【问题描述】:

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

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

当前代码:

import { FixedSizeList as List } from "react-window";

...

return (

   <table className="CargoListTable">
      <CargoTableHead />
      <List
        height={600}
        itemCount={cargoList.length}
        itemSize={35}
        width={900}
        itemData={cargoList}
        innerElementType="tbody"
      >
        {Row}
      </List>
   </table>
 )

const Row: React.FC<RowProps> = ({ index, style, data }) => {
  const cargo = data[index];
  return (
    <tr
      style={style}
      key={index}
    >
      <td>{cargo.registrationNumber}</td>
      <td>{cargo.pol}</td>
      <td>{cargo.pod}</td>
    </tr>
  );
};

【问题讨论】:

    标签: reactjs react-window


    【解决方案1】:

    对此的一种可能解决方案是将整个表格放在列表中。为此,我们可以使用 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>
    ));
    

    由于上下文,该元素知道粘性索引。并渲染头部和正文。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      相关资源
      最近更新 更多