React slot render can cause misalignment when horizontally scrollable
React slot render can cause misalignment when horizontally scrollable
Link to test case: https://stackblitz.com/edit/datatables-net-react-simple-miyesp?file=src%2FApp.tsx
Description of problem: Recently I noticed that as long as the table is horizontally scrollable (regardless of whether the scrollX
is enabled or not) or when you do enable it (regardless of whether table is horizontally scrollable or not), the slot rendering function leads to misalignment as the rendering continues after the init event. (See console log) And this leads to problems when calculating the column width!
In the demo case, I enabled the option scrollX
and the misalignment happens, once I comment it out, the misalignment issue is gone.
I know that we can use the columns.adjust()
to adjust the column inside the initEvent
, but the problem is that the render still proceed after the initEvent which may lead to wrong column width calculations.
See this demo case with columns.adjust()
inside initEvent
:
https://stackblitz.com/edit/datatables-net-react-simple-aplnwi?file=src%2FApp.tsx
NOTE: const api = table.current!.dt();
will always (or often) return false within initEvent
at runtime!! I have to wait until the rendering is completed. As in the demo case, I wait 1 second, which is really unreliable!
My second, slightly better temporary solution is to use setInterval
, which clears the interval when the reference is available.
See this demo case with setInterval
:
https://stackblitz.com/edit/datatables-net-react-simple-ylsfes?file=src%2FApp.tsx
Again, if the time is set too low, e.g. to 10 ms, there is still the chance that the result will be misaligned after multiple times of page reload.
I wonder is there any better solution for this issue?
Answers
The demo cases above use 2.1.4 (I modified from here). I've updated it to 2.1.8, but it's still the same.
I'm not sure if the latest commit will fix this issue or not.
IMO, using
columns.adjust()
could indeed work at some conditions. But we can see clearly the shift (adjustment) of the header after the initialization of the table. It would be more pleasant if the table was displayed directly without such shift. In some edge cases, when the table contains larger amounts of data, the adjustment can be made even later, making the shift more obvious (especially if the cell contains very long text in the render function).I'm not too suprised by that to be honest. I'd actually encorage scrolling to be disabled in this use case before of the potential for column misalignment. With React rendering content inside a cell, there is a lot of potential for the column width to be shifted.
If there was a way to know that the DOM content has changed via a hook or something, that I could listen for that and call
columns.adjust()
, but I'm not immediately aware of such an option. I'll look into options for that.One day browser's will support a scrolling
tbody
and that is going to make a massive difference.Allan