javascript - React.js: Set sticky table-header cell width based on corresponding table-row cell width - Stack Overflow

GoalI'm wanting to create a table with a scrolling body and a sticky header. The table header cell

Goal

I'm wanting to create a table with a scrolling body and a sticky header. The table header cell widths need to match their corresponding body column widths.

It's in React, and the Table ponent contain two separate ponents (one for the header, and another for the rows in the body). The content of the ponents will be ing from an outside source, so I can't make any assumptions on the widths of anything. The body of the table will have a lot of rows, so the table header is going to need to be sticky and stay at the top.

Problem

While the widths of the columns in the table body are automatically set, the widths are not automatically set in the table head. The table header widths need to be automatically set based on the contents of the table.

You can see the issue and my test code here:

Things to note

  • I'm open to using plugins or libraries if there's a good enough reason, but would rather not if possible
  • I've already tried react-sticky, which doesn't support table format
  • I've also tried react-sticky-table, which doesn't allow me to split the table into row ponents, which I need to do in order to help with more efficient rendering
  • Once again, I need the widths to all be set automatically. The only solutions I have seen so far involve setting the width in the header manually

Goal

I'm wanting to create a table with a scrolling body and a sticky header. The table header cell widths need to match their corresponding body column widths.

It's in React, and the Table ponent contain two separate ponents (one for the header, and another for the rows in the body). The content of the ponents will be ing from an outside source, so I can't make any assumptions on the widths of anything. The body of the table will have a lot of rows, so the table header is going to need to be sticky and stay at the top.

Problem

While the widths of the columns in the table body are automatically set, the widths are not automatically set in the table head. The table header widths need to be automatically set based on the contents of the table.

You can see the issue and my test code here: https://codesandbox.io/s/y0jx5rp081

Things to note

  • I'm open to using plugins or libraries if there's a good enough reason, but would rather not if possible
  • I've already tried react-sticky, which doesn't support table format
  • I've also tried react-sticky-table, which doesn't allow me to split the table into row ponents, which I need to do in order to help with more efficient rendering
  • Once again, I need the widths to all be set automatically. The only solutions I have seen so far involve setting the width in the header manually
Share Improve this question edited Jul 30, 2018 at 16:42 Adam 901 silver badge9 bronze badges asked Jul 30, 2018 at 15:45 ZachZach 8911 gold badge11 silver badges21 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 2

You can get the widths of your table cells by querying for them after rendering. To access a React ponent after rendering, we'll need to use a ref.

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

Pass it as a prop to the table body.

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

Then you can access it after rendering in ponentDidMount. If you remove, add or edit rows you may want to do it in ponentDidUpdate as well (but be careful not to make an infinite loop).

ponentDidMount() {
  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
  });
}

Then just use the width values in your state.

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

Here's a working version of your handy example.

I'm using react-sticky-table because I need an easy way to create a table with a freezable header and columns. You can't set the width of the cell using width but you can use max-width and min-width as a workaround, which is what I'm doing, to set the cell width. E.g.:

React/JS file:

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

CSS file:

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

pre-wrap makes sure that the text inside the cell breaks according to the available width.

Solution:

I did some CSS workaround with position sticky and fixed height for container, to make first column and first header sticky. It works great as expected. Here is working codesandbox URL, hope it helps!

I used most popular react-table package out there! https://codesandbox.io/embed/objective-frog-m4imr?fontsize=14&hidenavigation=1&theme=dark

There is an npm package for this that I remend that will save you time and energy. Check it out: react-sticky-table-thead All you have to do is to wrap a ponent around your table like:

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744224061a4563918.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信