[v9] Data update from external source doesn't trigger rerenders in components with table object references
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 38/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- react, typescript
- Bereich
- frontend
Rechercherichtung
Start with the StackBlitz reproduction, comparing table1's reusable createTableHook-based component with table2 and the documented React Compiler subscription example. Read the data and React Compiler documentation sections linked in the report, then trace how external data updates reach table.getRowModel(). Done means the behavior is reproducible and the correct reactive usage or required change is clearly established for externally updated data.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
TanStack Table version
v9.2.4
Framework/Library version
React 19.3.0
Describe the bug and the steps to reproduce it
The documentation mentions that in v9 the data is an atom which is not reactive from my understanding. A common scenario in many applications is extracting components for header, body, footer, even the whole table to have a single component to style and manage.
Especially with React Compiler enabled, I noticed that many reusable components via createTableHook were not rerendering, although I could see state updates in the devtools. The documentation explains this behaviour here, suggesting the following:
If a component depends on several state slices, subscribe to table.store and return all of those slices from the selector. Keep the state-dependent Table calls inside the Subscribe render function:
The selector must include every state slice that can change the result of table.getRowModel() for this table. That may include filtering, sorting, grouping, expansion, or pagination, depending on the features in use.
While I can use table.Subscribe to select the table feature states, I haven't found a way to subscribe to data changes other than to pass the whole data with prop drilling to sync data changes with consumer components (I still won't use the data, I will use row models, but at least this ensures row model consumers will be rerendered when data changes). There is an example that shows a reusable TableBody component, but this has the same issue: if data changes and table subscribed states are not the reason why (see scenarios below), the component will not rerender and stale data will be shown until a pagination, filter, sorting or any other subscribed feature state is updated.
There are several valid scenarios where this may be needed, cases where data may be externally updated and the table needs to rerender to show the latest state, such as:
- if
datais a React state, calling setState - using Tanstack Query, there is
polling,refetchOnWindowFocusor infinite query scroll event listeners - Websocket updates
In the sandbox you will find 2 tables and the realtime data from the state which I update every 2 seconds:
-
table1is based on a datatable component extracted viacreateTableHook, similar to v8 style reusable table components. While the documentation says that the changes indatawill cause the row models to be regenerated, thetableobject itself is a stable reference which has not changed (feature states have not changed), so althoughtable.getRowModel()returns different, new data, thetableobject doesn't trigger a rerender to reflect that since no subscribed state has been updated. -
table2is comes from an example from the documetation where the table reusable components are consumed in the same component where thedataandtablelive (Appin this case). While thetablerows update, I think this example is misleading in the documentation as the nested components are updated because theAppcomponent rerenders due tosetDatarather than the Tanstack Table internal signals. If I were to have a new component in between, soAppconsumesNewComponentwhich consumesDatatableBody, the table rows will not be rerendered just like in table1.
This behaviour theoretically could apply to any table option change as well (because they are not states), I don't know if this may be an issue or not for some users, just stating what I found. Also, while this behaviour is more evident in apps with React Compiler enabled due to a potential case of internal mutability, the same behaviour should happen without the compiler as well with manual memoization. The only difference is that without the compiler, by default if the data changes, it will be in the same or a higher component than the table components, so every component below will be rerendered, masking this issue.
I hope it's a valid issue and not me not understanding how to new state management works under the hood, wasting your time :(
What is the best way to handle this scenario where I want to have table data that may be updated externally?
What is the correct way to defined reusable components via createTableHook that are reactive to the row model changes? Are there any examples?
PS: Fantastic job on the v9 update btw, apart from this, I have been really enjoying it and the codebase looks cleaner than ever.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://stackblitz.com/edit/github-eyxvcbv9?file=src%2Fmain.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
- I agree to follow this project's Code of Conduct
- I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 28.5k
- Forks
- 3.6k
- Ø Merge
- 1 T. 3 Std.
- Gemergte PRs (30 T.)
- 22
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus TanStack/table
-
Cast required to access custom options when defining a custom plugin/featureEvtl. vergeben @sorena-paydar hat das vor 26 Tagen übernommen. Offen
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
Maintainer antworten meist innerhalb von 1 Tag
-
`aggregatedCell` not typed against bound `cellComponents` in `createAppColumnHelper`Evtl. vergeben @cpruijsen hat das vor 37 Tagen übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
TanStack/table#6577 · 6 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Leaf rows are not calculated correctlyEvtl. vergeben @sarathkumarsasi hat das vor 52 Tagen übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 55/100
TanStack/table#6573 · 4 Kommentare · 2 Reaktionen ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 48/100
TanStack/table#6524 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
Ähnliche Issues
-
Unsampled pageload span is profiled when profileLifecycle is 'trace' (browser UI profiling)Evtl. vergeben @Jxxunnn hat das heute übernommen. OffenBrowser Waiting for: Product Owner
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
getsentry/sentry-javascript#25497 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
e2e-failure ready-to-code
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 77/100
redhat-developer/rhdh-plugin-export-overlays#4438 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
resource: destroying a resource calls AbortController.abort() without a reason, creating an AbortError with a stack trace each timeEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offenarea: core
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
angular/angular#71422 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug status: needs triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
facebook/docusaurus#12739 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
factory-active task-identify-harness-labels-done task-identify-issue-type-done
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 68/100
vercel/ai#23537 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag