jasonbutz.info

Responsive Table With React and Bootstrap

Bootstrap, React

I’m currently working on an application for a friend to help him with his business. The application needs to be responsive since he may have employees perform certain actions from mobile devices.

In one part of the application there will be a table of inventory that employees can perform an action on. The table doesn’t work well on smaller screens so that is one area that requires a bit of extra work.

I figure there are two ways to adjust the layout for a smaller screen, JavaScript or CSS Media Queries.

For the JavaScript method I set a value in the component’s state that indicates which view should be used. That value is set via a method of the component that is called when the component is mounted as well as when the window is resized.

_evaluateMode() {
    let windowWidth = window.innerWidth;
    if (!this.state.cardMode && windowWidth <= 576) {
        this.setState({ cardMode: true });
    }
    else if (this.state.cardMode && windowWidth > 576) {
        this.setState({ cardMode: false });
    }
}

componentDidMount() {
    window.addEventListener('resize', () => this._evaluateMode());
    this._evaluateMode();
}

You can see the full example with CodePen:

See the Pen React Responsive Table - JS by Jason Butz (@jasonbutz) on CodePen.

This method worked fine, but I’m not thrilled by needing to re-render the components as the window resizes. At this point I was really hoping and expecting the CSS solution to be cleaner.

For the CSS solution I was able to mostly use Bootstrap’s built-in CSS classes, I just ended up having to add one class for it to work. To the table I added a cell that was usually hidden to the rows and just toggled the visibility of the cells in the table with the responsive classes.

You can see the full example with CodePen:

See the Pen React Responsive Table - CSS by Jason Butz (@jasonbutz) on CodePen.

Bootstrap’s responsive classes can be very powerful, you just have to wrap your head around how to make them work for you. One thing about this solution that may seem odd is having a <div> tag as a child of a <td> tag, but I checked the spec and that is completly acceptable. The <td> tag accepts flow content as a child and <div> tags can have anything that accepts flow content as their parent.