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

Jam*_*rch 6 typescript reactjs

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

基于Nitzan 的帖子展示了如何props从基类扩展,我创建了一个抽象类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
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

......并且还制作了一个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
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Mos*_*ini 9

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

由于您是 React 的新手,请查看https://reactjs.org/docs/composition-vs-inheritance.html

“在 Facebook,我们在数以千计的组件中使用 React,我们还没有发现任何我们建议创建组件继承层次结构的用例。”

  • @Mose,您好,所有 React 应用程序中的所有组件都_扩展_(继承)`Component` 而不是将组件作为字段/属性,这一事实怎么样?如果您想要一个基础“Component”,其“componentDidMount”对于应用程序中的所有组件都相同,该怎么办? (5认同)

Cù *_*iếu 7

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

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