I'm trying to write an abstract ReactJS class, then extend it. I'll thus need to extend its props
and state
(as far as I understand; I'm new to React).
Based on Nitzan's post showing how to extend props
from a base class, I made an abstract class Animal
:
import * as React from "react";
export interface AnimalProps {
isHibernatory: boolean;
}
export interface AnimalState {
shouldHibernate: boolean;
}
// TS2322: Type '{ shouldHibernate: boolean; }' is not assignable to type 'Readonly<S>'.
export abstract class Animal<P extends AnimalProps, S extends AnimalState>
extends React.Component<P, S> {
constructor(props: P) {
super(props);
this.state = {
shouldHibernate: props.isHibernatory
};
}
}
... And also made a class Cat
that extends it:
import * as React from "react";
import {AnimalProps, AnimalState, Animal} from "./Animal";
export interface CatProps extends AnimalProps {
isHairless: boolean;
}
export interface CatState extends AnimalState {
shouldSeekWarmth: boolean;
}
export class Cat extends Animal<CatProps, CatState> {
constructor(props: P) {
super(props);
this.state = {
willHibernate: props.isHibernatory,
shouldSeekWarmth: props.isHairless
};
}
}
However, as commented, the TypeScript compiler throws the error TS2322: Type '{ shouldHibernate: boolean; }' is not assignable to type 'Readonly<S>'
. I believe this is because it can't guarantee that S
will be readonly once it has extended AnimalState
. How else could I write this? Or am I missing a bigger picture?
An abstract class can extend another abstract class. And any concrete subclasses must ensure that all abstract methods are implemented. Abstract classes can themselves have concrete implementations of methods. These methods are inherited just like a method in a non-abstract class.
A class which is declared as abstract is known as an abstract class. It can have abstract and non-abstract methods. It needs to be extended and its method implemented. It cannot be instantiated.
When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, then the subclass must also be declared abstract .
Passing State to a Component To pass the state into another component, you can pass it as a prop. Then, inside <ExampleComponent /> , you can access the data as this. props.
React prefers composition over inheritance, may be this is a viable approach in some plain JS patterns but this is not the case.
As you are new to React, take a look at https://reactjs.org/docs/composition-vs-inheritance.html
"At Facebook, we use React in thousands of components, and we haven’t found any use cases where we would recommend creating component inheritance hierarchies."
I tried to cast the anonymous object to Readonly<S>
and the error went away.
this.state = { shouldHibernate: props.isHibernatory } as Readonly<S>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With