Why does my form default value not re-render?
Initially, I am in "/product-backlog" route. I navigate to "/product-backlog/task/edit/1" to edit my task name. Once I click the "Save" button, the edit is successful and I am able to observe the changes in my "/product-backlog" route. However, when I navigate back to "/product-backlog/task/edit/1", the default values of <input /> still shows the previous value, but if I were to navigate to "/product-backlog" and back to "/product-backlog/task/edit/1" again, this time the default values of <input /> shows the updated value.
I tried console.log() the props.task in <TaskEditor /> and I see that it logs 2 different values, the old value and the new value (2 times old, 2 times new in strict mode), while displaying the old value.
I thought by navigating from "/product-backlog/task/edit/1" to "/product-backlog" will cause my <TaskEditor /> to unmount, and so navigating back to "/product-backlog/task/edit/1" will cause a re-render and display the correct value but it didn't
Can anyone explain to me what is happening behind the scenes? Thank you
17 Replies
grumpy-cyan•9mo ago
please provide a complete minimal example by forking one of the existing stackblitz examples
eastern-cyanOP•9mo ago
@Manuel Schiller yes of course sorry
eastern-cyanOP•9mo ago
https://stackblitz.com/edit/tanstack-router-64qg2lw2?file=src%2Froutes%2Fproduct-backlog%2Findex.tsx
Ren Chiam
StackBlitz
Router Quickstart File Based Example (forked) - StackBlitz
Run official live example code for Router Quickstart File Based, created by Tanstack on StackBlitz
eastern-cyanOP•9mo ago
clicking on the pink task will navigate to the form route
and after changing the value by clicking submit
it will navigate back to the product backlog route and the new value can be seen
but if I were to press the same task that I change
in the form route I will see the old values
but if I click cancel and then go back to the form route by clicking the same task again
the new value can now be seen
grumpy-cyan•9mo ago
you need to invalidate the loader data
grumpy-cyan•9mo ago
StackBlitz
Router Quickstart File Based Example (forked) - StackBlitz
Run official live example code for Router Quickstart File Based, created by Tanstack on StackBlitz
grumpy-cyan•9mo ago
otherwise the loader does not rerun and router will use the stale values
eastern-cyanOP•9mo ago
@Manuel Schillerohh I see
but when exactly does the loader rerun, cause if i were to put console.log() in my TaskEditor component, after I change the value and return to the form to see my old value, the console first log the old value and then the new value
grumpy-cyan•9mo ago
it reruns when router.invalidate is executed
you can also await it
eastern-cyanOP•9mo ago
I meant like when router.invalidate() is not present though
grumpy-cyan•9mo ago
then it would only re-run when the stale time is reached
eastern-cyanOP•9mo ago
@Manuel Schilleroh okayy, thank you so much for taking the time
grumpy-cyan•9mo ago
this can also be nicely inspected via the devtools

grumpy-cyan•9mo ago
check the "cached matches" section
I think I misspoke here
what you see is routers 'stale-while-revalidate' behavior
so you navigate to a cached route, then the previous loader data is returned to your component
then the loader executes in the background, potentially updating the data
so it looks like your
TaskEditor
is not properly re-rendering when the new data arrives
by invalidating, you force the loader to re-execute when navigating there, so it solves the issue at hand
but at the cost of more latencyeastern-cyanOP•9mo ago
ohh okay that makes more sense thanks
grumpy-cyan•9mo ago
a solution to force re-rendering of that default value:
eastern-cyanOP•9mo ago
alright will do, seems more efficient