React.js:根据相应的表行单元格宽度设置粘性表头单元格宽度

时间:2018-07-30 15:45:56

标签: javascript html css reactjs

目标

我想创建一个带有滚动体和粘性标题的表。表标题单元格的宽度需要匹配其对应的正文列宽度。

它在React中,并且Table组件包含两个单独的组件(一个用于标题,另一个用于主体中的行)。组件的内容将来自外部来源,因此我无法对任何宽度进行任何假设。表格的主体将具有 lot 行,因此表格标题将需要保持粘性并停留在顶部。

问题

虽然表主体中列的宽度是自动设置的,但表头中的宽度不会自动设置。表格标题的宽度需要根据表格的内容自动设置。

您可以在此处查看问题和我的测试代码: https://codesandbox.io/s/y0jx5rp081

注意事项

  • 如果有足够的理由,我愿意使用插件或库,但如果可能的话,我宁愿不使用
  • 我已经尝试过react-sticky,它不支持表格格式
  • 我还尝试了react-sticky-table,这不允许我将表格拆分为行组件,这是我需要做的,以帮助提高渲染效率
  • 再一次,我需要全部自动设置宽度。到目前为止,我看到的唯一解决方案包括手动设置标题中的宽度

4 个答案:

答案 0 :(得分:2)

您可以通过在渲染后查询表格单元格来获得它们的宽度。要在渲染后访问React组件,我们需要使用ref。

constructor(props) {
  ...
  this.bodyRef = React.createRef()
}

将它作为道具传递给表体。

<tbody
  ...
  ref={this.bodyRef}
>

然后您可以在componentDidMount中渲染后访问它。如果要删除,添加或编辑行,则可能也要在componentDidUpdate中执行(但要注意不要造成无限循环)。

componentDidMount() {
  const row = this.bodyRef.current.children[0].children; // Get the children of one <tr>
  // the path from this.bodyRef.current to the children you need may vary.
  const headerWidths = [];
  for (let i = 0; i < row.length; i += 1) {
    headerWidths.push(row[i].getBoundingClientRect().width); // Get the rendered width of the element.
  }
  this.setState({
    headerWidths
  });
}

然后仅在您的状态下使用宽度值。

constructor(props) {
  ...
  this.state = {
    ...
    headerWidths: []
  }
}
...
render() {
  return (
    ...
    <th style={{ width: this.state.headerWidths[index] }}>
      ...
    </th>
  )
}

这是您方便的示例的有效版本。

Edit React Sticky Table-Header

答案 1 :(得分:1)

我正在使用react-sticky-table,因为我需要一种简单的方法来创建带有可冻结标题和列的表。您无法使用width设置单元格的宽度,但可以使用max-widthmin-width作为解决方法来设置单元格的宽度,这就是我正在做的事情。例如:

反应/ JS文件:

<Cell className='sticky-table-cell'>
    ...

CSS文件:

.sticky-table-cell{
      display: table-cell;
      min-width: 400px;
      max-width: 400px;
      white-space: pre-wrap;
    }

pre-wrap确保单元格内的文本根据可用宽度折断。

答案 2 :(得分:0)

解决方案:

我做了一些CSS解决方法,将位置固定并固定容器的高度,以使第一列和第一标题保持固定。它按预期效果很好。这是有效的codeandbox网址,希望对您有所帮助!

我在那里使用了最受欢迎的react-table 软件包! https://codesandbox.io/embed/objective-frog-m4imr?fontsize=14&hidenavigation=1&theme=dark

答案 3 :(得分:0)

我建议您使用一个npm软件包,以节省您的时间和精力。签出:react-sticky-table-thead,您要做的就是像在表周围包裹一个组件:

<StickyHeader>
  <table>
    <thead>
      <tr><th>Head</th></tr>
    </thead>
    <tbody>
      <tr><td>Data</td></tr>
    </tbody>
  </table>
</StickyHeader>