Reactjs React/TypeScript:使用附加属性扩展组件
我试图使用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
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 })
}
}
}