icflorescu / icflorescu/mantine-datatable

Changing base table columns causes rendering loop

Open
#759 12 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.3k
Forks
102
PR merge metrics
No merged PRs in 30d

Description

Describe the bug

I have been trying to track down a bug I have experienced in the InvenTree project

When using the useDataTableColumns hook, if the columns parameter changes, the order of rendered columns does not always match the provided order of columns.

To Reproduce
Steps to reproduce the behavior:

  1. Create a simple table with the useDataTableColumns hook, e.g.

 const myColumns = useMemo(() => {
    return [
        ...
    ];
 }, []);

  const tableColumns = useDataTableColumns({
    key: 'my-table',
    columns: dataColumns,
  });
  1. Render the table, which stores the column order data to local storage
  2. Insert a new column (into myColumns) which is not at the end
  3. The table will be rendered with the new column at the end.
  4. Additionally, there may be multiple (ongoing, repeated) re-render hooks due to the mismatch of input and displayed column ordering

Additional calls to setColumnOrder do not seem to fix the problem, as the column order is "locked in" on first rendering call.

Expected behavior

The displayed column order always matches the order of the supplied columns.

Additional context

I believe that the bug arises from this line:

https://github.com/icflorescu/mantine-datatable/blob/3ee01b0a3cb0de9b04fc2e20f00e3fded5084423/package/hooks/useDataTableColumns.ts#L123

In fact, I have resolved the issue entirely by commenting out this line.

So, this indicates that the alignedColumnsOrder is not being cached or updated correctly:

From:

https://github.com/icflorescu/mantine-datatable/blob/3ee01b0a3cb0de9b04fc2e20f00e3fded5084423/package/hooks/useDataTableColumns.ts#L41

  function alignColumnsOrder<T>(columnsOrder: string[], columns: DataTableColumn<T>[]) {
    const updatedColumnsOrder: string[] = [];
    columnsOrder.forEach((col) => {
      if (columns.find((c) => c.accessor === col)) {
        updatedColumnsOrder.push(col);
      }
    });
    columns.forEach((col) => {
      if (!updatedColumnsOrder.includes(col.accessor as string)) {
        updatedColumnsOrder.push(col.accessor as string);
      }
    });
    return updatedColumnsOrder;
  }

This function orders the columns by first looking in the stored columns, and then appending any newly detected columns after that.

However, there is a logic or sequence error which means that the old columns order is always written back to the localStorage.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in package/hooks/useDataTableColumns.ts, especially alignColumnsOrder and the line near 123 that writes the column order. Reproduce with useDataTableColumns, local storage, and a newly inserted column; trace why the old order is persisted. Done means supplied columns render in their supplied order and repeated re-render hooks stop occurring.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.