diff --git a/examples/preact/src/App.js b/examples/preact/src/App.js
index d96279fa4..f665b5ad5 100644
--- a/examples/preact/src/App.js
+++ b/examples/preact/src/App.js
@@ -3,12 +3,23 @@ import { hot } from 'react-hot-loader'
import Counter from './Counter'
import { Internal } from './Internal'
+const Inner = ({ children }) =>
{children}
+
+const indirect = {
+ element: () => (
+
+ indirect!
+
+ ),
+}
+
const App = () => (
- Hello, world!!
+ Hello, world!
+
)
diff --git a/examples/preact/src/Counter.js b/examples/preact/src/Counter.js
index 77627f434..1d0276786 100644
--- a/examples/preact/src/Counter.js
+++ b/examples/preact/src/Counter.js
@@ -4,7 +4,7 @@ import { h, render, Component } from 'preact'
/** @jsx h */
class Counter extends Component {
- state = { count: 0 }
+ state = { count: Math.round(Math.random() * 10) }
componentDidMount() {
this.interval = setInterval(
@@ -18,7 +18,7 @@ class Counter extends Component {
}
render() {
- return 10:{this.state.count}
+ return 100:{this.state.count}:1
}
}
diff --git a/examples/preact/src/hotLoaderSetup.js b/examples/preact/src/hotLoaderSetup.js
index 805df1c9d..97f0b0ac3 100644
--- a/examples/preact/src/hotLoaderSetup.js
+++ b/examples/preact/src/hotLoaderSetup.js
@@ -1,4 +1,34 @@
-import reactHotLoader from 'react-hot-loader'
-import preact from 'preact'
+import reactHotLoader, { compareOrSwap } from 'react-hot-loader'
+import preact, { setComponentComparator } from 'preact'
reactHotLoader.inject(preact, 'h')
+
+setComponentComparator(compareOrSwap)
+//(oldC, newC) => compareOrSwap(oldC, Object.getPrototypeOf(newC)));
+
+// changes to preact
+
+/*
+
+
+var defaultComp = (a,b) => a===b;
+
+var componentComparator = defaultComp;
+
+var compareComponents = (oldComponent,newComponent) => componentComparator(oldC,newC);
+
+var setComponentComparator = comp => {componentComparator = comp || defaultComp};
+
+
+//
+
+return hydrating || compareComponents(node._componentConstructor, vnode.nodeName);
+
+//
+
+isDirectOwner = c && compareComponents(dom._componentConstructor, vnode.nodeName),
+
+
+
+
+ */
diff --git a/src/proxy/createClassProxy.js b/src/proxy/createClassProxy.js
index 037710967..c951317d0 100644
--- a/src/proxy/createClassProxy.js
+++ b/src/proxy/createClassProxy.js
@@ -225,40 +225,47 @@ function createClassProxy(InitialComponent, proxyKey, options) {
// This function only gets called for the initial mount. The actual
// rendered component instance will be the return value.
- // eslint-disable-next-line func-names
- ProxyFacade = function(props, context) {
- const result = CurrentComponent(props, context)
-
- // simple SFC
- if (!CurrentComponent.contextTypes) {
- if (!ProxyFacade.isStatelessFunctionalProxy) {
- setSFPFlag(ProxyFacade, true)
- }
-
- return renderOptions.componentDidRender(result)
- }
- setSFPFlag(ProxyFacade, false)
-
- // This is a Relay-style container constructor. We can't do the prototype-
- // style wrapping for this as we do elsewhere, so just we just pass it
- // through as-is.
- if (isReactComponentInstance(result)) {
- ProxyComponent = null
- return result
- }
-
- // Otherwise, it's a normal functional component. Build the real proxy
- // and use it going forward.
+ if (1) {
ProxyComponent = proxyClassCreator(Component, postConstructionAction)
defineProxyMethods(ProxyComponent)
+ ProxyFacade = ProxyComponent
+ } else {
+ // eslint-disable-next-line func-names
+ ProxyFacade = function(props, context) {
+ const result = CurrentComponent(props, context)
- const determinateResult = new ProxyComponent(props, context)
+ // simple SFC
+ if (0 && !CurrentComponent.contextTypes) {
+ if (!ProxyFacade.isStatelessFunctionalProxy) {
+ setSFPFlag(ProxyFacade, true)
+ }
- // Cache the initial render result so we don't call the component function
- // a second time for the initial render.
- determinateResult[CACHED_RESULT] = result
- return determinateResult
+ return renderOptions.componentDidRender(result)
+ }
+ setSFPFlag(ProxyFacade, false)
+
+ // This is a Relay-style container constructor. We can't do the prototype-
+ // style wrapping for this as we do elsewhere, so just we just pass it
+ // through as-is.
+ if (isReactComponentInstance(result)) {
+ ProxyComponent = null
+ return result
+ }
+
+ // Otherwise, it's a normal functional component. Build the real proxy
+ // and use it going forward.
+ ProxyComponent = proxyClassCreator(Component, postConstructionAction)
+
+ defineProxyMethods(ProxyComponent)
+
+ const determinateResult = new ProxyComponent(props, context)
+
+ // Cache the initial render result so we don't call the component function
+ // a second time for the initial render.
+ determinateResult[CACHED_RESULT] = result
+ return determinateResult
+ }
}
}
@@ -360,7 +367,13 @@ function createClassProxy(InitialComponent, proxyKey, options) {
update(InitialComponent)
- proxy = { get, update }
+ const dereference = () => {
+ proxies.delete(InitialComponent)
+ proxies.delete(ProxyFacade)
+ proxies.delete(CurrentComponent)
+ }
+
+ proxy = { get, update, dereference }
proxies.set(InitialComponent, proxy)
proxies.set(ProxyFacade, proxy)
diff --git a/src/reconciler/hotReplacementRender.js b/src/reconciler/hotReplacementRender.js
index 9c578b70d..eb4fefc16 100644
--- a/src/reconciler/hotReplacementRender.js
+++ b/src/reconciler/hotReplacementRender.js
@@ -1,6 +1,6 @@
import levenshtein from 'fast-levenshtein'
import { PROXY_IS_MOUNTED, PROXY_KEY, UNWRAP_PROXY } from '../proxy'
-import { getIdByType, updateProxyById } from './proxies'
+import { getIdByType, getProxyByType, updateProxyById } from './proxies'
import {
updateInstance,
getComponentDisplayName,
@@ -58,7 +58,7 @@ const haveTextSimilarity = (a, b) =>
const equalClasses = (a, b) => {
const prototypeA = a.prototype
- const prototypeB = Object.getPrototypeOf(b.prototype)
+ const prototypeB = b.prototype // Object.getPrototypeOf(b.prototype)
let hits = 0
let misses = 0
@@ -348,6 +348,21 @@ const hotReplacementRender = (instance, stack) => {
}
}
+export const hotComponentCompare = (oldType, newType) => {
+ if (oldType === newType) {
+ return true
+ }
+
+ if (isSwappable(newType, oldType)) {
+ getProxyByType(newType[UNWRAP_PROXY]()).dereference()
+ updateProxyById(oldType[PROXY_KEY], newType[UNWRAP_PROXY]())
+ updateProxyById(newType[PROXY_KEY], oldType[UNWRAP_PROXY]())
+ return true
+ }
+
+ return false
+}
+
export default (instance, stack) => {
try {
// disable reconciler to prevent upcoming components from proxying.
diff --git a/src/utils.dev.js b/src/utils.dev.js
index 5f8e626f9..cc5f77316 100644
--- a/src/utils.dev.js
+++ b/src/utils.dev.js
@@ -1,4 +1,5 @@
import { getProxyByType } from './reconciler/proxies'
+import { hotComponentCompare } from './reconciler/hotReplacementRender'
import configuration from './configuration'
const getProxyOrType = type => {
@@ -9,4 +10,7 @@ const getProxyOrType = type => {
export const areComponentsEqual = (a, b) =>
getProxyOrType(a) === getProxyOrType(b)
+export const compareOrSwap = (oldType, newType) =>
+ hotComponentCompare(oldType, newType)
+
export const setConfig = config => Object.assign(configuration, config)