【问题标题】:difference between ClassicComponentClass and ComponentClass in reactJSreactJS中ClassicComponentClass和ComponentClass的区别
【发布时间】:2016-09-23 08:39:50
【问题描述】:

我为一些 reactJS 组件创建了我的打字稿定义,我看到在 react.d.ts 文件中有 2 个接口:

interface ComponentClass<P> {
    new(props?: P, context?: any): Component<P, ComponentState>;
    propTypes?: ValidationMap<P>;
    contextTypes?: ValidationMap<any>;
    childContextTypes?: ValidationMap<any>;
    defaultProps?: P;
    displayName?: string;
}

和:

interface ClassicComponentClass<P> extends ComponentClass<P> {
    new(props?: P, context?: any): ClassicComponent<P, ComponentState>;
    getDefaultProps?(): P;
}

我看到 ClassicComponentClass 扩展了 ComponentClass,但是什么时候应该使用其中之一呢? (为组件创建定义时)这是否取决于组件的创建方式?

【问题讨论】:

  • 为什么你需要任何一个?为什么不使用Component?这两个是组件类的接口而不是实例。在大多数情况下,您可以通过扩展 Component 创建自己的组件
  • 但我不创建自己的组件。我只为它创建定义。例如:声明模块“react-whatever”{ interface reactWhaterverProps{ id:number;名称:字符串; }\n 让 reactWhaterver: __React.ComponentClass\n 导出默认的 reactWhaterver;所以在这种情况下我不需要创建一些“状态”接口,因为它不是我的组件,它的状态对我来说是黑盒子,对吗?
  • 为什么不React.Component&lt;ReachWhateverProps&gt;?你到底想做什么?
  • 打字稿错误是不可能的,因为“组件”有 2 个参数

    。我只需要

    。我在DefiniteTyped 项目中为react 创建了一些定义。这是我的一个例子:github.com/DefinitelyTyped/DefinitelyTyped/blob/master/…

标签: javascript reactjs interface typescript definition


【解决方案1】:

我认为你错过了 ComponentClass 是什么。

这是一个简短的例子:

interface MyClassClass {
    new (): MyClass;
}

class MyClass {}

let ctor: MyClassClass = MyClass;
let instance: MyClass = new ctor();

在此示例中,MyClass 类似于 React.ComponentMyClassClass 类似于 React.ComponentClass

您的实际实例是组件而不是组件类,您应该使用它。
如果您不想指定状态,那么您可以简单地执行以下操作:

React.Component<ReachWhateverProps, {}>

编辑

首先,如果您的评论将来包含代码(跨越几行),那么只需编辑您的问题并添加代码并提出后续问题,然后添加一条评论,说明您已编辑您的问题,这将使代码更容易理解。

至于类与实例的区别,我认为最好的例子是javascript Array
如果您查看定义(在 lib.d.ts 中),您会看到(取决于它是 ES5 还是 ES6):

interface Array<T> {
    // array instance methods
}

interface ArrayConstructor {
    new (arrayLength?: number): any[];
    new <T>(arrayLength: number): T[];
    new <T>(...items: T[]): T[];
    (arrayLength?: number): any[];
    <T>(arrayLength: number): T[];
    <T>(...items: T[]): T[];
    isArray(arg: any): arg is Array<any>;
    prototype: Array<any>;
}

declare var Array: ArrayConstructor;

(来自 ES5 lib.d.ts

如您所见,所有实例成员/方法(例如lengthpush 等)都在Array&lt;T&gt; 接口中,ctor 函数和静态类函数(例如Array.isArray)在ArrayConstructor 定义。

在 javascript 中,类 ctor 只是使用 new 关键字调用的函数,因此:

class A {
    x: number;

    constructor(x: number) {
        this.x = x;
    }
}

编译成:

var A = (function () {
    function A(x) {
        this.x = x;
    }
    return A;
}());

所以A 基本上只是一个函数,而要创建一个实例,您只需:

let a: A = new A(5);

所以ctor接口是:{ new (x: number): A },或者:

interface AConstructor {
    new (x: number): A;
}

关于react,建议在propsstate中有实例数据,不要作为类成员。
这样做的原因是 Component 生命周期只知道这些并对它们的变化做出反应。
所以我会做这样的事情:

interface MyComponentProperties {
    id: string; 
    name: string;
}

class MyComponent extends React.Component<MyComponentProperties, {}> {
    render() {
        return <div className={ this.props.id }>{ this.props.name }</div>;
    }
}

let myComponent = <MyComponent id="mc4" name="my component 4" />

【讨论】:

  • 我想我明白了,所以如果我想为组件创建定义,我应该将组件视为关于将接口作为反应组件的构造函数并返回它的新实例的函数?所以结果将是:声明模块“some-react-component” { interface SomeReactComponent { id:number;姓名:任何; } 让 SomeReactComponent:new() => React.Component 导出默认 SomeReactComponent; } 正确吗?
  • 检查我修改后的答案,希望它能让事情更清楚
猜你喜欢
  • 2015-09-03
  • 2020-03-19
  • 1970-01-01
  • 2022-08-05
  • 2019-10-26
  • 2021-09-11
  • 2015-07-06
  • 2016-06-22
  • 1970-01-01
相关资源
最近更新 更多