Skip to content

Commit

Permalink
fix: transfer original prototype methods (#859)
Browse files Browse the repository at this point in the history
* safe define displayName, fix #845

* stand children did not exists, fix #843

* improve TS documentation

* add SSR+HRM example

* subrender - fix deferred updates

* transfer original class methods into the Proxy prototype, fixes #858

* fix tests
  • Loading branch information
theKashey authored and gregberge committed Feb 18, 2018
1 parent ffe0035 commit 0b7997f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 4 deletions.
2 changes: 1 addition & 1 deletion examples/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
"@types/react-dom": "^16.0.3",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-hot-loader": "next"
"react-hot-loader": "^4.0.0-beta.22"
}
}
39 changes: 36 additions & 3 deletions src/proxy/createClassProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ const has = Object.prototype.hasOwnProperty

const proxies = new WeakMap()

const blackListedClassMembers = [
'constructor',
'render',
'componentDidMount',
'componentWillReceiveProps',
'componentWillUnmount',

'getInitialState',
'getDefaultProps',
]

const defaultRenderOptions = {
componentWillReceiveProps: identity,
componentWillRender: identity,
Expand Down Expand Up @@ -72,7 +83,9 @@ function createClassProxy(InitialComponent, proxyKey, options) {
}

function proxiedUpdate() {
inject(this, proxyGeneration, injectedMembers)
if (this) {
inject(this, proxyGeneration, injectedMembers)
}
}

function lifeCycleWrapperFactory(wrapperName, sideEffect = identity) {
Expand All @@ -87,6 +100,24 @@ function createClassProxy(InitialComponent, proxyKey, options) {
}
}

function methodWrapperFactory(wrapperName, realMethod) {
return function wrappedMethod(...rest) {
return realMethod.apply(this, rest)
}
}

const fakeBasePrototype = Base =>
Object.getOwnPropertyNames(Base)
.filter(key => !blackListedClassMembers.includes(key))
.filter(key => {
const descriptor = Object.getOwnPropertyDescriptor(Base, key)
return typeof descriptor.value === 'function'
})
.reduce((acc, key) => {
acc[key] = methodWrapperFactory(key, Base[key])
return acc
}, {})

const componentDidMount = lifeCycleWrapperFactory(
'componentDidMount',
target => {
Expand Down Expand Up @@ -124,8 +155,9 @@ function createClassProxy(InitialComponent, proxyKey, options) {
return renderOptions.componentDidRender(result)
}

const defineProxyMethods = Proxy => {
const defineProxyMethods = (Proxy, Base = {}) => {
defineClassMembers(Proxy, {
...fakeBasePrototype(Base),
render: proxiedRender,
componentDidMount,
componentWillReceiveProps,
Expand All @@ -139,7 +171,7 @@ function createClassProxy(InitialComponent, proxyKey, options) {
if (!isFunctionalComponent) {
ProxyComponent = proxyClassCreator(InitialComponent, postConstructionAction)

defineProxyMethods(ProxyComponent)
defineProxyMethods(ProxyComponent, InitialComponent.prototype)

ProxyFacade = ProxyComponent
} else {
Expand Down Expand Up @@ -255,6 +287,7 @@ function createClassProxy(InitialComponent, proxyKey, options) {
} else {
checkLifeCycleMethods(ProxyComponent, NextComponent)
Object.setPrototypeOf(ProxyComponent.prototype, NextComponent.prototype)
defineProxyMethods(ProxyComponent, NextComponent.prototype)
if (proxyGeneration > 1) {
injectedMembers = mergeComponents(
ProxyComponent,
Expand Down
26 changes: 26 additions & 0 deletions test/proxy/consistency.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,32 @@ describe('consistency', () => {
proxy.update(Update2Class)
expect(instance.render()).toBe(42)
})

it('should stand-for all class members', () => {
class Initial {
constructor() {
this.methodB = this.methodB.bind(this)
}

methodA() {}

methodB() {}

render() {}
}

const proxy = createProxy(Initial)
const Class = proxy.get()
expect(Object.getOwnPropertyNames(Class.prototype)).toEqual([
'constructor',
'methodA',
'methodB',
'render',
'componentDidMount',
'componentWillReceiveProps',
'componentWillUnmount',
])
})
})
})

Expand Down

0 comments on commit 0b7997f

Please sign in to comment.