-
Notifications
You must be signed in to change notification settings - Fork 800
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
The Reconciler #711
The Reconciler #711
Conversation
let firstInstances | ||
let knownSignatures | ||
let didUpdateProxy | ||
import { |
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.
patch.dev was completely rewritten. Things like error reporting about failed registrations or failed replacement were removed, as long they are obsolete with reconciler.
Very good work! The idea is great! I think you have resolved the major issue of this project 😄. |
export default class ComponentMap { | ||
constructor(useWeakMap) { | ||
if (useWeakMap) { | ||
this.wm = new WeakMap() |
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.
We could rely on WeakMap since we are targetting only modern browsers.
@@ -2,16 +2,20 @@ import React, { Component } from 'react' | |||
import PropTypes from 'prop-types' | |||
import deepForceUpdate from 'react-deep-force-update' | |||
import { getGeneration } from './updateCounter' | |||
import hydrate from './reconciler/traverse' |
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.
hydrate / traverse
} | ||
} | ||
|
||
const deepForceTraverse = (instance, stack) => { |
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.
The goal of this function is to traverse a tree (stack) and swap all components is it right? I think the naming is not good.
} | ||
} | ||
|
||
export default function hydrate(instance) { |
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.
The goal is to traverse React tree and build an AST of it in order to traverse it and swap all swappable components, yes?
Ideally this should be moved into react-mount, as a user defined class comparison function. And, as result we could even remove proxy, as long there will be no need to fake types. |
@gaearon can help us! |
@theKashey we can't remove proxy because we have to keep state and variables. So even if we have a custom comparison function proxies are still needed. |
Please avoid relying on React internal APIs if you can. We don't want to introduce more dependencies than already exist in I intend to work on officially supporting hot reloading in React in the beginning of next year. So it's best to coordinate our efforts. |
@gaearon - does this mean, that we should not proceed with this PR, as long it uses some React internals, or we could proceed, as long it uses the same internals as deep-force-update? |
If it uses the same exact internals it’s okay. |
All |
@neoziro - just added a couple of tests. Coverage is not great, but enough for a start. Waive if you are keen to merge this to the lerna branch. |
@theKashey Thanks! I could take a look on tuesday, not before. |
I want to note that I still don't really understand what this is doing, so I'd appreciate a more in-depth explanation of why this works, why it is better than the existing approach, and what are the potential downsides and things that could break. That said I don't want to block you on my understanding :-) If you're sure this is solid and give it a lot of testing in large codebases (I'm sure plenty of people would be happy to volunteer trying an alpha) then let's roll with it. |
Ok, let me explain. The biggest constraint of V3 is a literal unusability for lots of people. All these folks who use decorators, recompose, and quite happy about it - they are all off the boat. V1 injects update code on the each-file-basic, thus allows it to perform point updates, and thus allows it to work with a complex code. But actually, it does not respect any complete code dependencies - module self-accept is a dangerous thing. V3 performs the work much more gently, rendering from top to bottom, relying on
Solution:
Reconsiler:
And
And there is a small trick here - reconsiler does not respect a possible change in props. It does not
So, this is not a real render, this is just another way to rehydrate hot updated code. |
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.
What is the behaviour if I remove an hoc:
// from
compose(one, two, three)(Component)
// to
compose(one, three)(Component)
@@ -99,6 +112,7 @@ AppContainer.propTypes = { | |||
}, | |||
errorReporter: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), | |||
warnings: PropTypes.bool, | |||
reconciler: PropTypes.bool, |
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.
I think we should always activate reconciler. Why making it optional?
@@ -99,6 +112,7 @@ AppContainer.propTypes = { | |||
}, | |||
errorReporter: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), | |||
warnings: PropTypes.bool, |
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.
So we can drop this option isn't it?
RE: // from
compose(one, two, three)(Component)
// to
compose(one, three)(Component) Reconciler will do it's best, and update all the proxies. But react-dom will not stand a tree change. |
This implements idea from #703
Fixes: #650 (HoC), #666 (HoC), and any other HoC or decorator issues.
Idea - instead of relying on registering the variables - relay on react-tree.
Algorithm is simple
render
the tree back, swapping the old components, and the new ones on the fly.Results
The good one - ANY component could be Hot-Reloaded. You can use complex HOC or decorators and still have RHL working🏆
The bad one - all components should be wrapped by proxy. This actually does not affect performance at all, as long stand-in operates on pure js prototypical inheritance.
To activate reconciler - add
reconciler
prop to AppContainer.PS: Not to be merged yet.