-
Notifications
You must be signed in to change notification settings - Fork 47.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fresh] Support classes by force-remounting them on edit #15801
Conversation
Details of bundled changes.Comparing: 73c27d8...f254e3a react-dom
react-art
react-test-renderer
react-native-renderer
react-reconciler
react-fresh
Generated by 🚫 dangerJS |
Would better classes retain state while doing this 🙂? |
There is no reliable way to retain state for classes without subtly changing semantics. We’ve intentionally opted to not do that. |
Decided to remove the second feature from this PR and focus it on classes. The other feature will need more work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems ok to me
return type.prototype && type.prototype.isReactComponent; | ||
} | ||
|
||
function areCompatible(prevType, nextType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tiny nit: This name is kind of vague and threw me at first
This hides the implementation a little bit and reduces how much React knows about the underlying mechanism.
We already have the logic to reset a component, so let's just reuse it instead of that special case.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
) * Remount classes during hot reload * Fix a crash when Hook isn't in scope inside the signature * Minor tweaks * Support a comment annotation to force state reset * Refactoring: pass a function instead of WeakMap This hides the implementation a little bit and reduces how much React knows about the underlying mechanism. * Refactor: use forceReset to remount unknown Hooks We already have the logic to reset a component, so let's just reuse it instead of that special case.
) * Remount classes during hot reload * Fix a crash when Hook isn't in scope inside the signature * Minor tweaks * Support a comment annotation to force state reset * Refactoring: pass a function instead of WeakMap This hides the implementation a little bit and reduces how much React knows about the underlying mechanism. * Refactor: use forceReset to remount unknown Hooks We already have the logic to reset a component, so let's just reuse it instead of that special case.
) * Remount classes during hot reload * Fix a crash when Hook isn't in scope inside the signature * Minor tweaks * Support a comment annotation to force state reset * Refactoring: pass a function instead of WeakMap This hides the implementation a little bit and reduces how much React knows about the underlying mechanism. * Refactor: use forceReset to remount unknown Hooks We already have the logic to reset a component, so let's just reuse it instead of that special case.
The first commit adds support for classes.
We don't need state preservation for classes. But we do need the opposite. When you edit a class, we want to remount its instances (and reset their state).
Remounting seems like it should already work. Because the type changes, and React is doing its thing. However, there is a case where that's not enough. If I edit
Button.js
that happens to be a class, other modules won't "see" the new export unless the update "propagates upwards". So ifModal.js
imports it, we'd have to re-executeModal.js
too. But that might also be a class. So we lose the locality of the edit — and in some cases it's even unsafe to re-execute arbitrary code above. (E.g. that breaks React Native once you get too close to top-level modules.) Inline requires or ES live imports sort of solve that, but not in all cases. Such as a cached element in state that already has a specific type.To solve that, we can stop update propagation at modules where all exports look like React components. (Functions or classes.) In case of classes, we want to remount all instances — and mount new versions. This should happen even for stale
<OldButton />
references in the tree. That's why I added the resolving mechanism to classes too. However, they would never attempt to preserve state.