ES7のdecoratorsでクラスを生成するとクラス名がそのデコレータのものになってしまいます。
例えば:
import React from 'react'
function addAwesomeProperty (Spec, Component = Spec) {
class AwesomeClass extends React.Component {
render () {
return React.createElement(
Component,
Object.assign({ awesome: 'yes!' }, this.props)
)
}
}
return AwesomeClass
}
@addAwesomeProperty
class OriginalClass extends React.Component {
...
}
こうすると生成後のクラスの名前は AwesomeClass
になってしまいます。これは不便。
だからといってクラス名を以下のように変えようとしても出来ません:
AwesomeClass.name = 'OriginalClass'
なぜなら name
プロパティは writable
ではないからです:
Object.getOwnPropertyDescriptor(AwesomeClass, 'name')
{ value: 'func',
writable: false,
enumerable: false,
configurable: true }
しかしES6の仕様によると以下の方法で変更できるとの記述を見つけました:
> Object.defineProperty(func, 'name', {value: 'foo', configurable: true});
> func.name
'foo'
という事は、前述の例を以下のように修正すればクラス名に影響を与えずに済みます:
import React from 'react'
function addAwesomeProperty (Spec, Component = Spec) {
class AwesomeClass extends React.Component {
render () {
return React.createElement(
Component,
Object.assign({ awesome: 'yes!' }, this.props)
)
}
}
// 追加
Object.defineProperty(AwesomeClass, 'name', { value: Component.name, configurable: true })
return AwesomeClass
}
まぁ、これが設計として正しいのかは謎です。
蛇足
動的なクラス名を定義する方法として、
const classes = { [ dynamicClassName ]: class { ... } }
classes[dynamicClassName].name // => dynamicClassName
みたいな方法もあるみたいだけど、自分の環境では常に _class
となって上手く行かなかった。
自分のbabelの設定が悪いのかもしれないけど。