Recursive forceUpdate
tgriesser opened this issue ยท 15 comments
It would be nice if there were a way to call forceUpdate
in a way that it would be applied recursively to children elements. I'm currently using shouldComponentUpdate
paired with Immutable.js in a similar fashion to OM and I've found that this behavior can be preferable in some cases.
One concrete use case would be @gaearon's hot loader - which currently attempts to gather all of the elements and trigger a forceUpdate
but it seems to still somehow be hitting shouldComponentUpdate
in my application (haven't quite tracked down where/how).
Another use case would be as a simple solution to #2517 (the context / shouldComponentUpdate
issue), when a context is changed you'd want to be able to forceUpdate
on the element and all children.
Unfortunately this wouldn't help me because I still need to walk the tree to auto-bind hot-patched methods.
it seems to still somehow be hitting shouldComponentUpdate in my application (haven't quite tracked down where/how).
Should not be the case, I specifically checked for this. If you can put up a reproducible example, I can take a look.
I also use something akin to Om, my state is completely outside of React in a single js-based Atom.
Everything is always re-rendered from the very top in a pure functional way.
I want to be able to hot swap the user language, and to retranslate the React app in the target locale without having to refresh the whole html page.
I use React-intl which uses context.
I would be OK with a recursive forceUpdate of the top component on locale change.
Related:
formatjs/formatjs#58
#2517
Note that I have tested to unmount and remount the top-level node with the updated context.
What I can see is that if you unmount and remount the node in the same "event loop tick", visually it looks like a recursive forceUpdate: the component is not unmounted but simply rerendered from a fresh vdom (i guess).
It seems this behavior is constant when unmounting/remounting in same event loop, and can also appear (randomly) when a setTimeout 0 is introduced.
Never mind, I realized this can be accomplished quite easily by just setting the key
to a unique value wherever you wish to remount the entire tree.
nice trick to know @tgriesser thanks
Quite useful, thanks @tgriesser
Never mind, I realized this can be accomplished quite easily by just setting the key to a unique value wherever you wish to remount the entire tree.
This would destroy the existing DOM though.
How about, when you change the context, walking all your children with React.Children.forEach
and calling forceUpdate on them if they have their contextTypes set to your context element?
If that works I think it would be neat if React had a helper function that did this. Screen size changes, translations, global edit mode, โฆ all kinds of seldom-changing things that benefit from being on context.
FWIW I maintain https://github.com/gaearon/react-deep-force-update for my hot reloading purposes but it relies on React internals.
Ok, for now I'll just stick to the safe side and continue using redux for data that would be better stored in context. Sometimes that means I have 50 of store listeners on the page but luckily that doesn't seem to impact performance for my use cases.
Hi!
At first, I'm aware of @gaearon's react-deep-force-update
but it seems it doesn't work on production build.
What I'm trying to solve is live retranslation of my page including re-executing router on feature/react-intl
branch of react-starter-kit
What I'm worrying about is when I use @tgriesser's trick I can loose internal state of components (controlled or uncontrolled inputs...)
I don't try the trick but I'm expecting that it can be too ๐ tricky for production..
Best if #2517 will be resolved and react-intl
will be updated, but what I can do in meantime? May be I'm just doing something wrong...
We'll likely get back to this. There's another issue about forceDeepUpdate
where it is tracked.