I have two favorite queries in google:
- What will happen if you throw scrap at the train toilet at full speed?
- What will happen if the component is replaced at full speed in the reactor?
And if with the first question everything is more or less clear, then with the second question everything is not so simple - Webpack-dev-server, Hot Module Replacement, and React-Hot-Loader immediately come out.
')
And everything would be fine, but this explosive mixture simply does not work, stumbling on the very first complex code, HOC, composition, decorator and native arrow functions.
In general, the third version of the Reac-hot-loader did not start at all.
Preamble
In fact, version 3 had 3 problems:
- react-proxy, which was used to "replace" the old version of the new component, and which was not at all friendly with the arrow functions, to which the context is nailed tightly.
- to ensure the work of bound and transpiled arrow functions, the babel plugin wrapped them in intermediate functions. Given the fact that he did this for ALL classes - this often led to breakdowns. Those in general, everything did not work.
- the principle of the search and substitution of components. For this, the babel plugin was used, which “registered” all the top-level variables, so that later it could be understood that “this is the variable”, in fact, “Big Key” and the proxy should be updated.
Everything is good, but the HOC can create a class within itself, and the decorator simply "decorates" the real variable. As a result, the render reactor will meet the “completely new” class at the place of the old one and spread out all the old wood.
Popular
wisdom says :
One of the most annoying things to set up with the Webpack is the Hotly working Module Module. This means that the components will keep their local state. Everything else makes HRM uselss (in my opinion).
In other words - without a normal preserve state, this RHL is not needed.
My journey to RHL began six months ago, when I tried for about a week (a lot) trying to understand how all these years people used React-hot-loader, because using it was unbearably painful. He brings nothing but pain. And then he opened PR, which silently began to suggest why and where the RHL will unmount the component, so that people can finally understand why it is not working. In order to somehow smooth the mental suffering.
And then I decided to fix everything on the vine.
Meet version 4!
I'll be brief - version 4 works almost always. She still has limitations that stem from the very nature of the phenomenon, but these “mistakes” are a guarantee of the correctness of the work. You can try now, just upgrade to version 4 of RHL.
What is HMR, RHL and all that?
HMR - hot swap modules. Built-in webpack and parcel mechanism that allows you to update individual modules on the client, when they change on the server. Just do not forget - this is only about the development. Without additional gestures silently refreshes the page.
RHL - react-hot-loader, a set of measures aimed at ensuring that React simply re-rendered the updated element and did nothing more.
RHL is something that provides the “right” HMR as it is needed.
There is an alternative theory that says HMR leads to monkey-patch, better TDD, BDD and all that. And there is such a big drop of truth in it.
Differences from version 4 to version 3
1. Instead of react-proxy, the
react-stand-in is used - a slightly more “javascript” solution. The main difference - standin is not a "wrapper", and not a proxy - this is a class that is
inherited from the real one.
This is a very tricky moment - when the time comes to replace one component with another - standin will simply change the prototype for itself (more precisely, the prototype of its prototype).
The result is that this never changes.
The second tricky moment is the transfer of changes made in the constructor (including those added to the constructor by the babel). Standin instantiates the old and new class, after which it looks for changes and tries to repeat them.
As a result, after updating the components, all changes are applied,
except for those made in componentWill / DidMount. Because mount / unmount did not occur, and it was precisely this that was required to be avoided.
2. Instead of “registrations” that are not friendly with HOC and decorators, a mechanism called “hotReplacementRender” is used.
When the time comes to “update”, the React-Hot-Loader component saves the old tree, and starts
to render the new one.
After the rendering of each element comes the time of "comparison" of old and new data, in fact, reconsiler.
If the new component is “very similar” to the old one - perhaps this is it, and a replacement can be made.
This approach easily breaks through any compositions, decorators, and any render-props in general. The only thing that does not survive is the change in the number or order of the children (if the key is not set), but this follows from the very nature of React.
3. Previously, many people stumbled over the moment HRM and RHL settings were configured. In the new version, the entire setting is limited to the _one_ command.
import React from 'react'; import {hot} from 'react-hot-loader'; const MySuperApplication = () => ...... export default hot(module)(MySuperApplication); <-----
The
hot (module) magic (MySuperApplication) will automatically configure the HMR for the current module, and the HOC portion of this function will wrap the MySuperApplication into the AppContainer.
EVERYTHING! (Plus babel-plugin don't forget)
Where does it work? Everywhere - Webpack, parcel, typescript (babel-plugin do not forget).
There are examples for everything.
Features of work, about which it is better to know
1. RHL v3 wrapped only “registered" components in a proxy. v4 wraps up everything. Theoretically, this should not affect the performance, but anything can happen.
2. Hot configures the current module as self accepted. Here we must understand that nothing but “reactant components” that RHL can survive to export from a module cannot be.
Standard errors now:
- use hot for local variables or even in the render (detectable and swear)
- use hot for HOC and functions - silently everything breaks down.
Hot - only for components.
3. If you start a timer in componentDidMount, and then change the function that this timer calls, it will not be updated. Because setTimeout has already received a reference to a function, and you cannot change it.
4. Code splitting - it is required either to wrap each component in hot which you are going to dynamically load, then it will update itself, or use a bootloader that is familiar with HMR / RHL.
- The popular
react-lodable is not suitable in principle. If you have it - no other options, cut how to wrap the components in hot - no. (do not forget that this does not affect the production)
-
loadable-components is a little better - they will try to update the file, but there may be problems, since “hotReplacementRender” will already be turned off when the import is triggered.
- 100%
react-imported-component works well, as it wraps the rendered component in AppContainer, and this “saves” the situation, but its SSR is a bit
specific , and not suitable for everyone.
5. I think this is not the end.
React-hot-loader is not a silver bullet - but rather a highly specialized tool that can be very useful. It may not be.
Time to try?
Right now we are close to the release of the RC version. Trite there are no more bugs to fix and add features. Only a little code coverage increase.
Now is the time to install RHL yourself, and try it out. And report all the problems that arise (of course!) Should not: D
In general - the fire!
github.com/gaearon/react-hot-loader/tree/next
npm install react-hot-loader @ next