React-🔥-Loader
@theKashey
React-🔥-Loader
That thing, which made Redux popular
🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥
❄❄❄❄❄❄❄❄❄
But how does it work?
Fast
Incremental build’s mate
😍 React-Hot-Loader 😍
Devloop
What You See Is What You Get
Design
Encourages frequent
changes
1. Code change
The root cause
2. Webpack HMR
It updates EVERYTHING until
something would “accept” the
change
3. React-DOM
Kills the previous tree with fire,
and creates a new one.
Update propagation flow
Not a whole application should be “hot”
Only that part
Don’t let
things, you
are not going
to update…,
update
Stop HERE
This is still fine. Please, don’t make it worse.
You will lose:
Local State
Components got remounted
Lifecycle effects
Everything above
Scroll position
DOM got updated
Focus
DOM got updated
Use React-Hot-Loader
The rest is our job
Move HMR “deeper”
Isolate the update, don’t let it “bubble”
<New /> !== <Old />
<A /> !== <A* />
<A key=“new” /> !== <A key=“old” />
REACT WILL 🔥 OLD TREE
{} !== {}
RHL IS LIKE A PAIN KILLER
just blocks the normal reconciliation process
RHL versions
v1
v3
v4
Version 1. Feb.2015-Nov.2016
- React < 15
- webpack-loader based
- patches modules exports
- wrapping them in transparent proxies
- if they duck like Reactish components
- and self module.accept modules
RHL versions
v1
v3
v4
Version 1. Feb.2015-Nov.2016
- React < 15
- webpack-loader based
- patches modules exports
- wrapping them in transparent proxies
- if they duck like Reactish components
- and self module.accept modules
<Old /> === <New/>
Use `react-proxy` to hide the real
component behind the scenes.
<Old/> !== <New />
They are different components, even if
they quack the same way.
https://medium.com/@dan_abramov/the-death-of-react-hot-loader-765fa791d7c4
Bonus: React 15 SFC
which always “quacks”
RHL versions
v1
v3
v4
Version 1. Feb.2015-Nov.2016
- React < 15
- webpack-loader based
- patches modules exports
- wrapping them in transparent proxies
- if they duck like Reactish components
- and self module.accept modules
v1
RHL versions
v3
v4
Version 3. Apr.2016-Nov.2017
- React 14-15-16
- babel-plugin based
- tracks top level variables
- wrapping them in transparent proxies
- when React uses them
v1
RHL versions
v3
v4
Version 3. Apr.2016-Nov.2017
- React 14-15-16
- babel-plugin based
- tracks top level variables
- wrapping them in transparent proxies
- when React uses them
<Stuff />.type !== Stuff
<Stuff />.type === proxy(Stuff)
https://github.com/gaearon/react-hot-loader/issues/304
Make it duck like
Component
Go through base prototype
and copy all stuff
How to proxy
Update
Redo step 2 on code update
Create a clone
Just an empty prototype
https://github.com/gaearon/react-proxy
https://github.com/gaearon/react-hot-loader/issues/391
☝”THIS”
=>
React-🔥-Loader
@theKashey
Back in 2017
I’ve tried RHL
And nothing worked…
https://medium.com/@antonkorzunov/how-to-hot-load-react-component-in-7-days-part-1-webpack-d8b77eea61eb
The “HOC” problem
https://codeburst.io/how-to-hot-load-react-component-in-7-days-part-2-react-28ce2b61d0c7
The “HOC” problem
https://codeburst.io/how-to-hot-load-react-component-in-7-days-part-2-react-28ce2b61d0c7
The first PRs
2(Two!) months to merge 1 day to merge
Fix the “HOC”Fix the Arrow
Goals:
Fix “HMR”
Wrap export
with `hot`.
(works for webpack,
parcel, Electron)
Read how
HMR works.
Try to apply.
Cry aloud.
HMR BEFORE HOT AFTER
Make it duck like
Component
Go through base prototype
and copy all stuff
How to proxy
Update
Go thought every mounted
components and redo step 2
Create a clone
Just an empty prototype
Cherry-pick
Create “old” and “new”
classes and cherry-pick state
changes
How to stand-in
Update
Replace prototype of a
prototype
and everything would be
updated
Inherit from
Component
Just an empty prototype
https://github.com/theKashey/react-stand-in
That does
not solve
“Arrow”
You cant “copy” an arrow function
We injected `eval` to
every single class
`eval` is prototype-based method, so it would be called in a “new” reality
https://github.com/gaearon/react-hot-loader/issues/969
That does
not solve
“HOC”
We created our own
React renderer!
As seen at: react-async-component, loadable-components, relay
Old Tree Temp Tree Real Tree
If it walks like a <Component /> 
and it quacks like a <Component />,
then it must be a <Component />
then register it as a `auto${counter++}`
SFC has a signature (props, context)
Where to get “the (react 15) context”?
So - we’ve wrapped SFCs with a
Class
Don’t be like us
That was, and still is, our biggest
maintenance pain for a long while.
That’s both terrifying and… terrific
Mistakes?
That DID not
solve “Arrow”
There is an issue created last week…
We should get back
some “bridging” stuff
from v3
HOT, or
NOT?
`hot` was actually not quite “hot”
A year later we added
`react-hot-loader/root`
😎 resilient to errors this
time.
Wrapping
was an issue
And v4 “hot-renderer” was wrapping
E-V-E-R-Y-T-H-I-N-G!
We added “cold” API
to selectively disable
RHL influence.
v3
v1
RHL versions
v4
Version 4. Jan.2018-present
- React 14-15-16
- babel-plugin based
- tracks top level variables, and
discovers the rest in runtime
- wrapping them in transparent proxies
- when React uses them
v3
v1
RHL versions
v4
Version 4. Jan.2018-present
- React 14-15-16
- babel-plugin based
- tracks top level variables, and
discovers the rest in runtime
- wrapping them in transparent proxies
- when React uses them
was
UNTIL…
https://github.com/storybookjs/storybook/issues/4691
Cos there were no SFCs
Cos we wrapped them with Classes
to track context
for the hot-renderer…
https://github.com/preactjs/preact/issues/1007
1. That was “HOC” problem
2. RHL needs “old” VDOM to compare
3. There is no VDOM in Preact
https://github.com/preactjs/preact/pull/1120
https://github.com/reactjs/rfcs/pull/74
https://github.com/hot-loader/react-dom
⚛React: Are Component1 and Component2 the
same?
⚛React: Nope?! Burn everything!
Before '
⚛React: Are Component1 and Component2 the
same?
🔥Loader: Hey React! I’ve made Component1 and
Component2 the same.
⚛React: Hm, very strange, but Yes!
Before '
⚛React: Are Component1 and Component2 the
same?
🔥Loader: la, la-la, la-la-la-la…..
🔥Loader: (just say yes!)
⚛React: Yes!
After 😎
⚛React: Are MemoComponent1 and
MemoComponent2 the same?
🔥Loader: Yes. Oh Gosh! sorry, but I just dropped your
cache
⚛React: Are LazyComponent1 and LazyComponent1*
the same?
🔥Loader: Yes, let me call `import` for you
No more Proxies needed**
<App />.type === App
No need for custom renderer*
**v4.10*v4.12
Remove
Proxies from
classes
Add Hooks
reloading
support '
4.9.0 4.10.0
Hooks
reloading?
RHL adds itself as a dependency to
any hook with dependencies.
- keep STATE
- keep REFS
- don’t time travel life cycle effects (like with classes)
- drop Memo
- rerun “synchronisation” effects
WHAT
ABOUT
CHANGING
HOOKS?
Error would
be shown
<4.9.0 4.9.0
1. On HMR, `componentDidThrow` is
injected to ALL (class) components.
2. In case of emergency Page Error,
or Inline Error is shown.
3. The change got reverted.
https://twitter.com/theKashey/status/1072626544135335936
Local tree
remount
Error would
be shown
<4.9.0 4.9.0
🍋
react-refresh
https://github.com/facebook/create-react-app/issues/7227
React 16.9+React 14, 15,
16 support
🔥 🍋
- Classes
- FC
- working from “outside” (patch)
- not 100% “safe” without 🔥-patch
- no time travel
- 100500 lines of code
- “safe” classes
- FC
- working from “inside” (DevTools)
- 100% safe
- time travel
- 500 lines of code
all?
Our code is (yet) bloated with Classes.
Enter a shiny hook world - and it
would be refreshing hot. Like coffee ☕
Mistakes?
Eat your own
dog food*
Comments are
developers best
friends!
BIG MISTAKE BIGGER MISTAKE
Keep them close to the code
*Don’t forget The Goal
**The goal is not “hot-reloading”,
The Goal is the better DX!
React- 🔥 -Loader
@theKashey

The History of React-Hot-Loader