gaearon / gaearon/react-hot-loader
Reversed Hot-Replacement
- Dominant language
- JavaScript
- Stars
- 12.2k
- Forks
- 775
- PR merge metrics
- No merged PRs in 30d
Description
parent issue: #1121
is an action for: #1024
There are huge problems updating Class-based components. We fight with them for a year, and look like there is only one way to defeat them - surrender.
### How it works currently
- RHL set prototype from a `new` class to an `old` class
- As long as the class constructor could not be "updated" or "redone" we have to "find" updates manually
- RHL creates `new` and `old` classes, looks for differences (not all of them are visible)
- __overrides__ class variables to replicate changes on the real instances (not all changes are replicatable) using `eval` injected by the babel plugin to maintain the "variable scope" (which might be wrong)
In short - it __lands__ some important "changes" from hot-updated code to the existing ones. Maintaining the state just because it is not updated. The result could be far from reality.
- the prototype-based methods are all "new", they are all right
- any other method update is )transported_ from a new (variable) scope to an old one
- some operations, performed in a constructor, could not be redone and skipped
### Proposal
- create a new component from a scratch, as we are doing
- detect any difference between the `old` component and instance, as we are going
- inject all changes we want to __keep__ to the new instance
- replace old instance by a new one on fiber level.
- update refs if they existed (probably could be done on createElement level)
In short - __keeps__ some important changes, like state or lifetime variables. The result is a reality, the same as if you refresh a page.
This is actually a _refresh_, but with a state kept (and we don't need anything else)
The only difference - we should inject a new instance deeply to `react-dom`.
- 👍 react 16 only
- 👍 babel plugin is __not__ required, as long there is no need to inject updated code to existing classes.
- 👍 any third party code, like [`react-redux` should be hot-reloadable](https://github.com/reduxjs/react-redux/pull/1137) without any change from their side.
- 👍 no more type comparison problem
- 👎 react-🔥-dom is required
It might be a blocker. The more we patch sources of react, the deeper we are in trouble. This this proposal is something, that _should be done_, I am not sure that it's something, that _could be done_.
Contributor guide
Research direction
Start by reading parent issue #1121 and action issue #1024, then trace how React 16 and react-dom currently handle hot replacement of class-based component instances. Done would require a concrete, reviewed design for replacing instances at the fiber level while preserving selected state and refs, plus a feasible implementation plan.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- frontend, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 18/100