网站搜索

javascript - 如何在子类中访问 this.props,在覆盖父类函数的函数中


我想在子函数中使用 this.props.childName,这个子函数是在父函数中定义的。但会出现 TypeScript 编译错误(Property 'name' does not exist...)。如果我使用 this.props.parentName,就没有问题。我如何才能访问子类的 this.props?

interface Prop<T> {
  parentName: string
}

class Parent<T> extends React.Component<Prop<T>, State<T>> {
  constructor(props: Prop<T>) {
    super(props)
  }
  printName() {}
}

interface PropChildren<T> {
  childName: string
}

class Child<T> extends Parent<string> {
  constructor(props: PropChildren<T>) {
    super(props)
  }

  printName() {
    console.log(this.props.childName) // here I want to use children prop but compile error
  }
}

答案#1

你的子组件继承了父组件,并且父组件中 props 的类型是 Prop<T>,它只包含属性 parentName。

为了在子组件中将 props 的类型设为 PropChildren,你应该这样声明:

class Child<T> extends React.Component< PropChildren<T>, State<T>> {
    // ...
}

顺便说一下,你不需要将你的 props 接口做成泛型(带 <T>)。泛型只在接口可以在不同上下文中使用不同数据类型时才使用。

根据你的评论,这里是一个示例,说明如何将父组件的行为与子组件共享,同时仍然能够为子组件的 props 定义不同的数据类型:

interface PropParent {
    parentName: string
}

class Parent<TProp extends PropParent> extends React.Component<TProp, State> {
    constructor(props: TProp) {
        super(props)
    }
    printName() {}
}

interface PropChildren extends PropParent {
    childName: string
}

class Child<T> extends Parent<PropChildren> {
    constructor(props: PropChildren) {
        super(props)
    }

    printName() {
        console.log(this.props.childName)
    }
}

答案#2

首先,除非你需要在不同地方使用,否则接口中不需要任何泛型。其次,Child 类也应该继承自 React.Component,而不是它的父类。所以下面可能是一段更好的代码

import React from 'react'
interface IParentProps {
  readonly parentName: string;
  readonly children?: JSX.Element 
}
interface IPropsChild {
  readonly childName: string;
}
class Parent extends React.Component<IParentProps> {
  constructor(props: IParentProps) {
    super(props)
  }
  printName = () => {

  }
  render() {
    return <Child childName={this.props.parentName} />
  }

}
class Child extends React.Component<IPropsChild> {
  constructor(props:IPropsChild) {
    super(props)
  }
  printName = () => {
    console.log(this.props.childName)
  }
}