I'm extending a base class and overriding a method in the base class. But when I call it, it calls the super class version. How do I override the method?
var Hello = React.createClass( {
getName: function() { return "super" },
render: function() {
return <div>This is: {this.getName()}</div>;
}
});
class HelloChild extends Hello {
constructor(props) {
super(props);
console.log( this.getName());
}
getName()
{
return "Child";
}
};
I want it to print "This is: Child" but it prints "This is: super"
The problem is that you're mixing ES6 type class declaration (ex. Hello) with old school Javascript declaration (ex. HelloChild). To fix HelloChild, bind the method to the class.
class HelloChild extends Hello {
constructor(props) {
super(props);
this.getName = this.getName.bind(this); // This is important
console.log( this.getName());
}
getName()
{
return "Child";
}
};
Then it'll work.
I found the answer (adapted from here: https://gist.github.com/Zodiase/af44115098b20d69c531 ) - the base class needs to also be defined in an ES6 manner:
class Hello extends React.Component {
//abstract getName()
getName()
{
if (new.target === Hello) {
throw new TypeError("method not implemented");
}
}
render() {
return <div>This is: {this.getName()}</div>;
}
};
Actually you can override method to execute code from your subclass
class Hello extends React.Component {
getName() {
super.getName();
}
}
class HelloChild extends Hello {
getName()
{
return "Child";
}
}
Please note that this answer proposes different approach:
I wonder why you should do this in the first place, my point is that directly coupling two react components is not a right way to implement re-usability in React.
If you are trying to have multiple child components which extends one parent, What I would do is, to have child components and a higher-order component and then implement common functionality with Composition. This way you can skip those methods, which you were trying to override and so everything would stay clear.
Related
In a library that I wish to extend without modifying its code, several classes inherit from the same imported one. That is in this BaseClass I would need to overwrite a specific method.
In the library (written in TypeScript) :
import { BaseClass } from './base_class';
export class ClassA extends BaseClass {}
import { BaseClass } from './base_class';
export class ClassB extends BaseClass {}
…
In the external extension I wish to write :
import { BaseClass } from 'library';
export class ExtendedBaseClass extends BaseClass {
oneMethod() {
const data = BaseClass.prototype.oneMethod.call(this);
// make additional things with data
return data;
}
}
Is there a way for this new ExtendedBaseClass to become the parent of all ClassXs ? At least in a new extended and re-exported version of them without the need to copy their internal code.
Is there a way for this new ExtendedBaseClass to become the parent of all ClassXs?
No.
An alternative might be to replace the one method directly on the base class:
import { BaseClass } from 'library';
const oneMethod = BaseClass.prototype.oneMethod;
Object.defineProperty(BaseClass.prototype, 'oneMethod', {
value() {
const data = oneMethod.call(this);
// make additional things with data
return data;
},
});
There's no way to do exactly what you're asking, but you could achieve the same result by extending each class individually.
ExtendedClassA extends ClassA {
oneMethod() {
// call a shared method if you need to reuse
}
}
// ExtendedClassB, etc
I understand sub classing with extends for example
class Car extends Vehicle {}
class Dog extends Animal {}
But with React, you may see
class HelloMessage extends React.Component {}
What does the dot between React and Component mean? How does it work in React and in vanilla Javascript?
Classes do not have to be standalone variable names - they may be properties of objects as well. So extends React.Component, absent any other context of what React is, just means that React is an object with has a Component property which is a class.
For an example of how to emulate this in vanilla JS:
const obj = {
Foo: class Foo {
doThing() {
console.log('doing thing');
}
}
};
class MySubClass extends obj.Foo {
subMethod() {
console.log('submethod');
}
}
const s = new MySubClass();
s.doThing();
s.subMethod();
React is doing the same sort of thing. It's just a way to organize data as properties of objects.
This is my main class (it uses a subclass:)
import SubClass from './SubClass'
class MainClass extends classes(SubClass) {
constructor () {
// some code
}
}
window.MainClass = new MainClass()
export default MainClass
This is the subclass:
class SubClass {
constructor () {
this.someMethod = function () {
// some code
}
}
}
export default SubClass
If I want to use a method from the SubClass I can write: MainClass.someMethod.
How to modify this code so I write: MainClass.SubClass.someMethod instead?
So I can write:
MainClass.SubClass.someMethod
MainClass.SubClass2.someMethod
In case I need another SubClass?
I think you need to call super(). And classes() seem doen't need to be added.
When used in a constructor, the super keyword appears alone and must be used before the this keyword is used.
See document
import SubClass from './SubClass'
class MainClass extends SubClass {
constructor () {
super();
console.log(this.someMethod)
}
}
Hope this help
I need to extend the two classes from the same namespace.
for ex:
declare namespace myNameSpace{
class class1{
///some methods will be here
}
class class3 extends class1{
//some method wil be here
}
class class2 extends myNameSpace. class3 {
//some methods will be here
}
export namespace class2 {
//declaration will be here
}
}
i need to extend the 'myNameSpace.class1' class as well as 'class2' namespace.
class newClass extends myNameSpace.class1, myNameSpace.class2 {
constructor() {
super();
}
}
If i call the both the classes, i got an error message
classes can only extend a single class
Is there any other way to fix this issue in typescript.
Is there any other way to fix this issue in typescript.
TypeScript is single inheritance by design.
You can use mixins but you can't override methods (unless you write a custom applyMixins methods)
Using the method:
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
}
You have to implement (on empty way)
class NewClass implements myNameSpace.class1, myNameSpace.class2 {
// empty implementation
public methodFrom1 : ()=>void;
public methodFrom2 : ()=>number;
constructor() {
// no super()
}
}
now use mixing to actually make it multi extend classes:
applyMixins(NewClass, [myNameSpace.class1, myNameSpace.class2]);
and now you can create the class
const foo = new NewClass()
foo.methodFrom1() // actually calls nameSpace.class1.prototype.methodFrom1
I am currently trying to figure out a way to assign methods to the super object in a class, in order to extend a functionality inside a class.
I want to create a "Component" class and have each class that extends the "Component" class have different methods depending on the component needs. I want to use the term "describe" for the method that would extend the super object. Therefore, I am describing the component.
Here is an example:
class Component {
constructor (args) {
this.template = args.template;
}
getTemplate () {
return this.template;
}
describe () {
//The magic should happen here
}
}
Class Controller describer
class Controller {
constructor () {
}
getEvents () {
return {};
}
}
Extending the Component class.
Then, using the "describe" method to inject other methods from other classes.
class example extends Component {
constructor () {
super({template: '<div></div>'});
super.describe({
Controller
});
super.getTemplate();
super.getEvents();
}
}
var app = new App({
example
});
Is it possible? Thank you :)