React/TypeScript: extending a component with additional properties

前端 未结 5 597
梦如初夏
梦如初夏 2021-02-01 16:05

I am trying to use react to recreate my currents components (written in pure typescript) but I can\'t find a way to give additional props to a component extending an other.

相关标签:
5条回答
  • 2021-02-01 16:23

    The most elegant solution that I found (without extra generic class) is

    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>
            );
        }
    }
    
    0 讨论(0)
  • 2021-02-01 16:29

    You'll need to make DataTable generic so that you'll be able to use an interface which extends 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
        }
    }
    
    0 讨论(0)
  • 2021-02-01 16:31

    For those who need, base classes can declare required/abstract methods that all instances must implement:

    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
      }
    }
    
    
    0 讨论(0)
  • 2021-02-01 16:33

    as a rule of thumb it is probably better to avoid inheritance. luckily TS and react are great tools allowing that (unlike c# for example, where inheritance often saves you a bunch of boilerplate)

    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>
        }
    }
    
    0 讨论(0)
  • 2021-02-01 16:39

    Keep in mind that what you are doing is an anti-pattern. React recommends using composition over inheritance.

    "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."

    More info: https://reactjs.org/docs/composition-vs-inheritance.html

    0 讨论(0)
提交回复
热议问题