Repository navigation
Tanstack v9 still doesn't really support react compiler #6577
Description
Activity
Unless there's a concrete proposal on how to actually make this better, I don't think it can be improved much more. I'm happy to be proved wrong though. The only way to make it even more "compatible" with the react compiler would be to fundamentally change the state management nature of this library. We're already aware that passing the table object as a prop won't properly cause react re-renders, but that's just how the react compiler works, and we've documented that here.
@KevinVandy improving compatibility is not the main concern here. The main concern is that you are claiming compatibility while not actually following the rules putting your users at risk of future breakage. It also puts the React team in a awkward position when evolving the compiler in the future as they might have to avoid optimizations that should be legal but would break libraries like this.
One solution would be to make the library fully compatible for sure but the alternative in my opinion is to clearly document the lack of compatibility and guide users into using directives to opt out of compilation for components using it.
Relying on patterns that clearly still break the rules of react and documenting how users should skirt around the exact optimizations the compiler happens to implement right now seems irresponsible. Either it follows the rules and users can use the compiler or it doesn't and users should opt out of the compiler. At the very least users should be made aware of the risk they are taking if they leave the compiler on for these components.
@GabbeV Can you point out the problem areas, because I honestly thought that we are doing it as correctly as we can right now, and that any gaps are covered in our react compiler guide that I linked above.
There is nothing in my playground breaking your documented rules as far as i can tell, demonstrating how your rules are already insufficient for the transforms the compiler implement.
@GabbeV Am I talking to an AI agent or you? You are not being helpful at all here, so I cannot find the core issue that we would need to address.
@KevinVandy There is no AI involved. I wrote my last comment as a follow up to my comment before without seeing your answer. Wasn't intended as some kind of quick answer to your comment.
The playground is showing how unrelated useDeferredValue useDebugValue make header3 header4 .getIsSorted() break while identical reads of getIsSorted() for header1 and header2 works. Click the buttons to see the "Working: " lines update while the "Not working:" stay stuck.
I'm unsure where my point isn't coming across as you didn't acknowledge the repro in your response, admitted you understand the incompatibility by claiming more compatibility would require other state management, and then asked me to explain the compatibility gap.
The rules of React require state, props and values returned from hooks to be immutable. That doesn't just mean the top level object as React assumes it can replay the render and get the same result. Your current .getHeaderGroups() etc are not allowed to return live values just because they are functions and not properties, that is till breaking the rules of React. I assume you already know this though.
A compiler compatible version of tanstack table would as you yourself explained require different state management patterns or at least a changed api using useSyncExternalStore etc. This core issue isn't about fixing compatibility or adding another caveat to how you should avoid sending some values to hooks or something. This core issue is about how I think you shouldn't be advertising compatibility while breaking the rules the compiler rely on to decide on what transformations it can do, even if the current version of the compiler happens to mostly work.
TanStack Table version
9.1.2
Framework/Library version
React 19.2.8
Describe the bug and the steps to reproduce it
Tanstack table uses internally mutable state, something that goes against Reacts immutability assumptions. This creates issues with the react compiler. v9 tries to make it work with the compiler by making the table object a non stable object. This happens to work out in many cases, not because it now follows the rules of react but because exactly how the compiler currently reason about those rules often shake out that way. Depending on internal implementation details like this and advocating for your users to leave the compiler on for components using tanstack table seem irresponsible as a future version of the compiler could suddenly break your users apps.
The attached stackblitz shows how sending a value to a completely unrelated hook can cause react compiler to make different decisions, breaking something that previously worked out. To me this demonstrates that what tanstack table is doing is still fundamentally breaking the react compilers rules and could break at any time.
This is causing issues with Octane as well as it wants to rely on similar assumptions as the react compiler for its optimizations. That is probably not your issue to solve but mentioning it as well as it was through investigating weird decisions around memoization in Octane that I discovered this issue. octanejs/octane#846 (comment)
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://stackblitz.com/edit/vitejs-vite-deapj37r?file=src%2FApp.tsx
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
None
Terms & Code of Conduct