React/TypeScript:扩展具有附加属性的组件

IT技术 reactjs typescript
2021-05-13 10:44:00

我正在尝试使用 react 来重新创建我的 currents 组件(用纯typescript编写),但我找不到一种方法来为扩展另一个组件的组件提供额外的props。

export interface DataTableProps {
    columns: any[];
    data: any[];
}

export class DataTable extends React.Component<DataTableProps, {}> {
   render() {
       // -- I can use this.props.columns and this.props.data --
   }
}

export class AnimalTable extends DataTable {
    render() {
       // -- I would need to use a this.props.onClickFunction -- 
    }
}

我的问题是我需要给 AnimalTable 一些与 DataTable 无关的props。我怎样才能做到这一点 ?

4个回答

您需要DataTable通用,以便您能够使用扩展的接口DataTableProps

export interface AnimalTableProps extends DataTableProps {
    onClickFunction: Function;
}

export class DataTable<T extends DataTableProps> extends React.Component<T, {}> { }

export class AnimalTable extends DataTable<AnimalTableProps> {
    render() {
        // this.props.onClickFunction should be available
    }
}

对于那些需要的人,基类可以声明所有实例必须实现的必需/​​抽象方法:

import { Component } from 'react'


abstract class TestComponent<P = {}, S = {}, SS = any> extends Component<P, S, SS> {
  abstract test(): string
}


type Props = {
  first: string,
  last: string,
}

type State = {
  fullName: string,
}

class MyTest extends TestComponent<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = {
      fullName: `${props.first} ${props.last}`
    }
  }

  test() {
    const { fullName } = this.state
    return fullName
  }
}

根据经验,避免继承可能更好。幸运的是 TS 和 react 是允许这样做的好工具(例如,与 c# 不同,继承通常为您节省了一堆样板)

export interface DataTableProps {
    columns: any[];
    data: any[];
}

export class DataTable extends React.Component<DataTableProps, {}> {
   render() {
       // -- I can use this.props.columns and this.props.data --
   }
}

export type AnimalTableProps = DataTableProps & {
    onClickFunction: () => void;
};

export class AnimalTable extends React.Component<AnimalTableProps, {}> {
    render() {
        const {onClickFunction, ...tableProps} = this.props;
        // use onClickFunction however you need it
        return <DataTable {...tableProps}></DataTable>
    }
}

我发现的最优雅的解决方案(没有额外的泛型类)是

interface IBaseProps {
    name: string;
}

class Base<P> extends React.Component<P & IBaseProps, {}>{

}

interface IChildProps extends IBaseProps {
    id: number;
}

class Child extends Base<IChildProps> {
    render(): JSX.Element {
        return (
            <div>
                {this.props.id}
                {this.props.name} 
            </div>
        );
    }
}