如何为组件编写一个抽象类(具有可扩展状态和道具)?

时间:2018-01-02 13:11:09

标签: reactjs typescript

我正在尝试编写一个抽象的ReactJS类,然后对其进行扩展。因此,我需要扩展其propsstate(据我所知;我是React的新手)。

基于显示如何从基类扩展props的{​​{3}},我创建了一个抽象类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
        };
    }
}

...还制作了一个扩展它的课程Cat

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
        };
    }
}

但是,如评论所述,TypeScript编译器会抛出错误TS2322: Type '{ shouldHibernate: boolean; }' is not assignable to type 'Readonly<S>'。我相信这是因为它无法保证S一旦扩展AnimalState就会只读。我怎么能写这个?或者我错过了更大的图片?

2 个答案:

答案 0 :(得分:4)

React更喜欢组合而不是继承,在某些普通的JS模式中,这可能是一种可行的方法,但事实并非如此。

如您不熟悉React,请查看https://reactjs.org/docs/composition-vs-inheritance.html

“在Facebook,我们在数千个组件中使用React,而且我们没有找到任何建议创建组件继承层次结构的用例。”

答案 1 :(得分:2)

我试图将匿名对象强制转换为Readonly<S>,错误就消失了。

this.state = { shouldHibernate: props.isHibernatory } as Readonly<S>;