Preact flushing entire components using react-hot-loader
See original GitHub issueHi guys,
I had a tough day trying to make preact work with react-hot-loader v3 but at least I have discovered why.
The problem I had was that preact was flushing an entire form component when typing on an input, it was supposed to just re-render the input. Unmounting and mounting the component make the input lose the focus and the form is not usable anymore.
After much investigating the problem was that react-hot-loader uses proxies in order to create instances of the components, see: https://github.com/gaearon/react-hot-loader/blob/master/src/patch.dev.js#L106
Using RHL, when a component is created using inst = new Ctor(props, context)
by preact we are not getting an instance of Ctor, but an instance of a copy of Ctor created by the proxy.
That makes that inst.constructor !== Ctor
so the next time that the component get rendered, preact tries to build it from the VNode and finds that dom._componentConstructor !== vnode.nodeName
and it decides to unmount it.
I understand this is not preact’s fault, but it’s so easy to fix just modifying one line of code of preact, overriding inst.constructor = Ctor
for all components:
if (Ctor.prototype && Ctor.prototype.render) {
inst = new Ctor(props, context);
Component.call(inst, props, context);
} else {
inst = new Component(props, context);
inst.render = doRender;
}
// Override the constructor even if the instance was created by `new Ctor()`
// This will make preact work ok with react-hot-loader using proxies to create instances
inst.constructor = Ctor;
If I create a PR would you merge it? It’s my missing piece to finally make preact and react-hot-module work together!
Thanks for preact, it’s great!
Issue Analytics
- State:
- Created 6 years ago
- Comments:30 (15 by maintainers)
Top GitHub Comments
FYI: We now have an official HMR solution for Preact called prefresh. We recommend everyone switching over to use that 🎉
@theKashey it’s the opposite, it’s working really well with v4. Just returning an empty stack from
getReactStack
. Preact re-renders the dom nicely, preserving the state.