-
Notifications
You must be signed in to change notification settings - Fork 50
Description
(Note: I encountered this while using react-transform-webpack-hmr
, but I believe the issue to be internal to createProxy
.)
When using a @decorator
function that copies the original component-class into a new one, static
properties specified using ES7 initializers are unaccounted for.
For example, here's a slightly modified version of App.js
from react-transform-boilerplate
:
import React, { Component } from 'react';
// This is TypeScript's implementation of Extend:
var __extends = function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
function decorate (BaseComponent) {
function DecoratedComponent (...args) {
console.log("Running decorated constructor!");
BaseComponent.apply(this, ...args)
}
__extends(DecoratedComponent, BaseComponent);
return DecoratedComponent;
}
@decorate
class Number extends Component {
static defaultProps = {
value: 1,
};
render() {
return <h1>{this.props.value} (defaultProps={'' + Number.defaultProps})</h1>;
}
}
export class App extends Component {
render() {
return (
<div>
<Number />
<Number value={42} />
</div>
);
}
}
We expect the rendered output to look like this:
For some reason, Counter.defaultProps
is not transferred in TypeScript's implementation of __extends
when it is defined with ES7 generators.
It may have something to do with how __extends
uses hasOwnProperty
, but I'm not familiar enough with how react-proxy
works under the hood to really take a stab at what might be going on, here.
- If I remove the
@decorator
, it works as expected. - If I change
@decorator
to use ES6'sextends
, (i.e.class DerivedComponent extends Component ...
), it works as expected. - If I specify
defaultProps
after the decorator runs (i.e.Counter.defaultProps = ...
), it works as expected.
I first encountered this problem when using react-free-style
, which is written in TypeScript and provides a decorator function that extends components.
The natural workaround is to avoid static ES7 property initializers, but many of us are already using them, as encouraged by React.
I forked react-transform-boilerplate
to make it easier to reproduce the problem:
git clone https://github.com/namuol/react-transform-boilerplate-es7-initializer-bug
cd react-transform-boilerplate-es7-initializer-bug
npm install
npm start
open http://localhost:3000