Prevent table column resize/jump when you search table rows (React version)

Rendering with table in react is really easy, you just need to map through the result and return whatever should be shown as each TR, below is an example how you render table in react.

  
    YourObjectArray.map((item, index) => (
      <tr>
        {item.name}
        {item.birth}
        {item.age}
      </tr>
    ));
  

here comes a problem that I faced when working with table, lets say there is a search box somewhere and let you search the table for results and returns rows that matches your search, however each rows have different titles or some contents, and by default table will stretch to based on your content. Lets use some packages for example: react-sort-search-table and you can directly go to their demo, so see what I am talking about here

Try a search in the search bar with something “asdkjhaskdjahskjdh”, and soon you will realise that the header column jump, or text in header row change position. Now lets try to fix this problem, the usual way is to use fixed table or set the width of each column using

… but we don’t want to fixed the table, we want it to be dynamic based on its content, the idea is to create a hidden row and set width inside td > div so that width of this div will not be blank when you make a search the hidden row still there and force the columns to stop jumping around.

Lets create a hidden row and div for each cell also set the width for the div so that it will fixed a div width.

  
    getHiddenWidthRow = () => {
      const firstTableRow = document.querySelector("tbody tr");

      if (firstTableRow) {
        return [...Array(firstTableRow.cells.length).keys()].map((item, idx) => (
          
            
)); } };

But you might also want to change the width when resize, lets add eventListener to window resize:

  
  componentDidMount() {
    if (this.urlInput) {
      this.urlInput.focus();
    }
    window.addEventListener("resize", this.handleWindowResize);
  }

  componentWillUnmount() {
    window.removeEventListener("resize", this.handleWindowResize);
  }
  

  handleWindowResize = () => {
    if (this.props.projectsCount > 0) {
      const tableHiddenRow = document.getElementById("hiddenWidthRow");
      const tableHiddenRowTD = [...tableHiddenRow.getElementsByTagName("td")];

      tableHiddenRowTD.forEach((item) => {
        item.children[0].style.width = 0;
        item.children[0].style.width = `${item.offsetWidth}px`;
      });
    }
  };

I hope this will help you in your next project, here is a full implementation of the script.