33

This is part ES6 question part React question. I'm trying to use namespaced components in React with ES6 classes and Babel. So I guess the real question is how to name space es6 classes so I can do what is explained here: https://facebook.github.io/react/docs/jsx-in-depth.html#namespaced-components

Since I get an unexpected token error:

class Headline extends Component { ... }

class Headline.Primary extends Component { ...
              ^
1
  • 1
    I think you problably should be working with modules since ES6 does not have the concept of namespaces. Commented Aug 26, 2015 at 15:42

3 Answers 3

38

The ECMAScript-6 class declaration syntax expects a standard BindingIdentifer as the class name. A dot is not a valid character inside an identifier name.

In the context used in the link in OP, the "namespace" is an object, and properties are added to that object one by one using the dot notation for property access.

You could replicate that by using a class expression instead:

'use strict'

var ns = {}

ns.MyClass = class {
  constructor() {
    console.log('in constructor')
  }
}

new ns.MyClass()

Sign up to request clarification or add additional context in comments.

6 Comments

Yeees, yeeeesss, this is what I was looking for! Didn't know you can write like something.something = class extends something.baseSomething{}
This approach with an anonymous class seems to fail when combined with extends. :(
@faintsignal Does it really? It should work fine, as the name in a class expression is optional.
@caw I really wish I had taken a moment to elaborate and/or include a fiddle when I made that comment, as I cannot recall the specifics. Perhaps some kinks were worked out of the engine(s) since my remark.
@faintsignal That was my guess as well. Probably some bug that has been fixed since. It works today, and the spec seems to allow for that, too.
|
26

This doesn't really change with ES6, you still will have to do an assignment:

Headline.Primary = class Primary extends Component { … };

However, using classes like Headline as namespaces is getting pretty deprecated with ES6 (and has previously been a questionable practice anyway), you should instead leverage the new module system. Export Primary as a named export, and instead of importing the Headline class rather do import * as headlines from ….

4 Comments

You can safely change class Primary to just class and make it an anonymous class expression. (Otherwise, that name Primary (without the namespace prefix) would be available within that class in addition to the prefixed name.)
@caw No, named class expressions don't make the identifier available in their scope, unlike named function expressions. It's just making the name explicit (and, in some cases, necessary to give the constructor its .name property)
@Bergi They do! Both functions and ES6 classes behave exactly the same in that regard. What you’re referring to when you say that it’s making the name “explicit” is that function (and class) names can be automatically inferred since ES6, which means the name for the function (or class) expression is often superfluous. But still, the function (or class) expression could have a name different than the variable or property it is assigned to, in which case the expression’s name will be available within the scope of that expression additionally.
@caw Oh, you're right! I did not know about classScope, thanks.
17

This link also relates to this question.

In the Module objects section, it is described that you can do something like this:

// headline.js file
export {Headline, Primary}
class Headline {}
class Primary {}

// In another module...

import * as Headline from "headline";

let h = new Headline.Headline();
let hp = new Headline.Primary();

It's not exactly what you are trying to do, but is an alternative.

Another way of doing it is almost like @Bergi has already pointed out, but I'm just clarifying it further:

let Headline = class Headline extends Component { }
Headline.Primary = class Primary extends Component { }

export {Headline as default}

// in another module:
import Headline from 'headline';

let headline = new Headline();
let primary = new Headline.Primary();

2 Comments

Regarding your second snippet, you wouldn't do * as with that default export, would you?
That's right. I've copied and pasted the line and forgot to edit this. Thank's =]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.