Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs React/TypeScript:使用附加属性扩展组件_Reactjs_Typescript - Fatal编程技术网

Reactjs React/TypeScript:使用附加属性扩展组件

Reactjs React/TypeScript:使用附加属性扩展组件,reactjs,typescript,Reactjs,Typescript,我试图使用react来重新创建当前的组件(用纯typescript编写),但我找不到一种方法来为扩展其他组件的组件提供额外的支持 export interface DataTableProps { columns: any[]; data: any[]; } export class DataTable extends React.Component<DataTableProps, {}> { render() { // -- I can use

我试图使用react来重新创建当前的组件(用纯typescript编写),但我找不到一种方法来为扩展其他组件的组件提供额外的支持

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 -- 
    }
}
导出接口DataTableProps{
列:任何[];
数据:任何[];
}
导出类DataTable扩展React.Component{
render(){
//--我可以使用this.props.columns和this.props.data--
}
}
导出类AnimalTable扩展数据表{
render(){
//--我需要使用this.props.onclick函数--
}
}

我的问题是,我需要给Animatable一些与DataTable无关的道具。我该怎么做

您需要将
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
    }
}
导出接口AnimalTableProps扩展了DataTableProps{
onclick函数:函数;
}
导出类DataTable扩展React.Component{}
导出类AnimalTable扩展数据表{
render(){
//此.props.onClick函数应可用
}
}

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

接口IBaseProps{
名称:字符串;
}
类基

扩展了React.Component{ } 接口IChildProps扩展了IBaseProps{ id:编号; } 类子扩展基{ render():JSX.Element{ 返回( {this.props.id} {this.props.name} ); } }


根据经验,最好避免继承。幸运的是,TS和react是实现这一点的好工具(例如,与c#不同,在c#中,继承常常为您节省大量样板文件)

导出接口DataTableProps{
列:任何[];
数据:任何[];
}
导出类DataTable扩展React.Component{
render(){
//--我可以使用this.props.columns和this.props.data--
}
}
导出类型AnimalTableProps=DataTableProps&{
onClick函数:()=>void;
};
导出类AnimalTable.Component{
render(){
const{onClickFunction,…tableProps}=this.props;
//使用onclick函数,但需要它
返回
}
}

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

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

从'react'导入{Component}
抽象类TestComponent扩展组件{
抽象测试():字符串
}
类型道具={
第一:字符串,
最后:弦,,
}
类型状态={
全名:string,
}
类MyTest扩展了TestComponent{
建造师(道具:道具){
超级(道具)
此.state={
全名:`${props.first}${props.last}`
}
}
测试(){
const{fullName}=this.state
返回全名
}
}

创建组件的完整示例,您可以扩展并维护状态和道具

import { Component } from "react";

// Props for the Base Component
export interface BaseComponentProps { }

// State for the Base Component
export interface BaseComponentState {
    isLoaded?: boolean
}

// The Base Component that your components can extend
export class BaseComponent<Props extends BaseComponentProps, State extends BaseComponentState, SS = any> extends Component<Props, State, SS> {

    State: BaseComponentState = {
        isLoaded: false
    }

    constructor(props: Props) {
        super(props);
    }

    componentDidMount() {
        this.setState({ isLoaded: true })
    }
}

// Props for your specialized component
export interface MainComponentProps extends BaseComponentProps {

}

// State for your specialized component
export interface MainComponentState extends BaseComponentState {
    CanRead: boolean
}

// Your component which now extends the BaseComponent
export class MainComponent extends BaseComponent<MainComponentProps, MainComponentState> {
    state: MainComponentState = {
        CanRead: false
    }

    componentDidMount() {
        super.componentDidMount();

        if (this.state.isLoaded) {
            this.setState({ CanRead: true })
        }
    }
}
从“react”导入{Component};
//基础组件的道具
导出接口BaseComponentProps{}
//基本组件的状态
导出接口BaseComponentState{
isLoaded?:布尔值
}
//组件可以扩展的基础组件
导出类BaseComponent扩展组件{
状态:BaseComponentState={
isLoaded:false
}
建造师(道具:道具){
超级(道具);
}
componentDidMount(){
this.setState({isLoaded:true})
}
}
//专用组件的道具
导出接口MainComponentProps扩展BaseComponentProps{
}
//说明您的专用组件
导出接口MainComponentState扩展BaseComponentState{
CanRead:boolean
}
//您的组件现在扩展了BaseComponent
导出类MainComponent扩展了BaseComponent{
状态:MainComponentState={
CanRead:错
}
componentDidMount(){
super.componentDidMount();
if(this.state.isLoaded){
this.setState({CanRead:true})
}
}
}

谢谢@Nitzan Tomer!构造函数中有问题,无法正常使用。状态TS2322:类型“{…状态属性}”不可分配给类型“Readonly”。@meteor如果没有看到您的代码,很难说是什么问题。试着问一个新的问题并把相关的代码放在那里。考虑使用<代码>抽象>代码>类/函数。()@meteor您需要使用您指定的。。。导出类DataTable扩展React.Component{constructor(t:t){super(t);}}}希望这对其他人有帮助。我将在下面发布一个完整的示例,使用
abstract
类/函数。()
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
  }
}

import { Component } from "react";

// Props for the Base Component
export interface BaseComponentProps { }

// State for the Base Component
export interface BaseComponentState {
    isLoaded?: boolean
}

// The Base Component that your components can extend
export class BaseComponent<Props extends BaseComponentProps, State extends BaseComponentState, SS = any> extends Component<Props, State, SS> {

    State: BaseComponentState = {
        isLoaded: false
    }

    constructor(props: Props) {
        super(props);
    }

    componentDidMount() {
        this.setState({ isLoaded: true })
    }
}

// Props for your specialized component
export interface MainComponentProps extends BaseComponentProps {

}

// State for your specialized component
export interface MainComponentState extends BaseComponentState {
    CanRead: boolean
}

// Your component which now extends the BaseComponent
export class MainComponent extends BaseComponent<MainComponentProps, MainComponentState> {
    state: MainComponentState = {
        CanRead: false
    }

    componentDidMount() {
        super.componentDidMount();

        if (this.state.isLoaded) {
            this.setState({ CanRead: true })
        }
    }
}