问题描述
我想使用语义 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
我们需要两个简单的元素来呈现 StickyRow
和 Row
元素。您可以在此处添加 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>
));
由于上下文,该元素知道粘性索引。并呈现标题和正文。
如果满足您的需要,可以进一步简化此代码。