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 { ...
^
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()
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 ….
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();
Related
Hello i am using some module behavior and it ask me a question.
in one.js :
import { Two } from './two.mjs';
export class One extends Two<<<ReferenceError {
}
in two.js :
import { One } from './one.mjs';
export class Two {
constructor() {
let one = new One();
}
}
Ok it's not a casual case and it's not really my code but i have simplified.
I know why this error append (the interpreter go in file two then import the file one and in the file one the class Two is not initisialized)
But the question is : How can i find (like in java) a way to avoid this (use only one file, avoid class, idk). Give me your opinion.
Thx a lot.
I am new to React and was learning propTypes and the ways to implement them in React. One of the ways of propType implementation is via class fields, that is,
class Foo extends React.Component {
static PropTypes = {};
}
The question is why need to use static for propTypes and is it ok to omit static? I really hope for your beginner-friendly explanation since I have looked through the answer here react: why static propTypes but did not properly understand WHY?
Static props are those that belong to the class, not to an instance. This means that one class is shared throughout the entire application. This is known as the singleton pattern. The reason you would do this is because propTypes do not belong to a single instance, as mentioned in the question you linked. propTypes are used for type checking the props passed in, so there is no need for them to be tied to specific instances:
https://blog.logrocket.com/validating-react-component-props-with-prop-types-ef14b29963fc/
It is not OK to omit static, because the PropTypes library is expecting a class property when it looks for your prop definitions. If you omit static, you are defining an instance property, which is not how the library operates. Omitting the keyword will result in an instance property and your props will not be validated as expected.
If the static keyword is confusing, just think of it as doing the same exact thing as the following:
class Foo extends React.Component {
static propTypes = {}
}
// equivalent to
class Foo extends React.Component {}
Foo.propTypes = {}
I have a project using a function class.
the webpack config part of the output is something like below:
...
output: {
library: 'FirstPoint',
...
FirstPoint is first point to access main class, and main class at index.js (entry point) is something like:
import { onInit } from './intilize'
import { showSomeThing } './somthing'
export function MyClass(props) {
onInit()
}
MyClass.prototype.showFoo = showSomeThing
the full example for this:
let myClass1 = new FirstPoint.MyClass()
let myClass2 = new FirstPoint.MyClass()
myClass1 .showFoo() //not show myClass1 detail, use last instance detail (myClass2)
after the run, all thing is done. just after creating another instance the showFoo method that using a function outside main class keep last value from the last instance.
I want to make instance for all new object that defines from MyClass class, Or, in other words, is there a way that I can import all the imported modules into the first level, ie, the main class, and instead of the output (production version) of an array of modules, there is only one modulus, and within that other modules, like the function?
One method for doing this, is using encapsulation, and the other way use a Param class!
I try to use a decorator to add some method or property to an annotated class.
This is my decorator :
export default function Component(params) {
return function decorator(target) {
target.template = params.template;
console.log(target, params.template);
}
}
I used it this way :
#Component({
template: template
})
export default class App {}
But when I use this class :
app.template // undefined;
Any idea?
You are modifying class object itself, i.e.
App.template // your template is here
and you just defined a static property for App class in this case.
In order to set template for class instances you should use:
target.prototype.template = params.template;
(Good example that classes are actually just syntactical sugar over constructor functions and prototype-based inheritance).
Also, I think this article about combining mixins and decorators might be helpful.
I'm trying to use Flowtype in an AngularJS (1.5) project but it complains about the $inject annotation. What is the correct way to handle this?
Flow version 0.30.0
Example code
navigation/links-controller.js
export default class LinksController {
constructor(navigationService) {
this.availableLinks = navigationService.availableLinks;
}
}
LinksController.$inject = ['NavigationService'];
navigation/index.js
...
import NavigationService from './navigation-service';
import LinksController from './links-controller';
export default angular.module('app.links', [uirouter])
.config(routing)
.service('NavigationService', NavigationService)
.controller('LinksController', LinksController)
.name;
Example flowtype output
LinksController.$inject = ['NavigationService'];
^^^^^^^ property `$inject`. Property not found
The reason for this is that by creating a class you are defining its interface in Flow.
When you are assigning $inject to the class you are effectively adding a new property that was not defined in the class interface and that is a type error in Flow.
You have two options for making this type check in Flow:
Adding a static property type definition:
class LinksController {
static $inject: Array<string>;
constructor() {...}
}
LinksController.$inject = ['NavigationService'];
Adding a static property:
class LinksController {
static $inject = ['NavigationService'];
constructor() {...}
}
With the second option you are going to need to enable esproposal.class_static_fields=enable within the [options] section of your .flowconfig
Because this is a proposal not yet added to the JavaScript standard and not available in any browsers, you will also need to compile it with something like Babel (you'll need either the stage-2 preset or the transform-class-properties plugin).
If you are using external dependency injection then you might want to link the functions like below.
angular
.module('app',[])
.controller('LinkCtrl', LinkCtrl);
LinkCtrl.$inject = ['NavigationService'];
Can you please share your full snipper if you have exactly done like above?