【问题标题】:How to type a React component definition?如何键入 React 组件定义?
【发布时间】:2014-10-03 16:52:05
【问题描述】:

我正在尝试静态键入 React 组件的 props。在包含definitions for React 之后,我定义了React.createClass 的类型化变体,命名为component

interface Component<P> {
    (props: P, ...children: any[]): React.ReactComponent<P, any>
}

function component<P, S>(spec: React.ReactComponentSpec<P, S>): Component<P> {
    return React.createClass(spec);
}

当我定义一个带有注释的 Label 组件时,它表示它需要一个 text 字符串属性,

var Label: Component<{text: string}> = component({
    render: function() {
        return React.DOM.div(null, this.props.text);
    }
});

var App = React.createClass({
    render: function() {
        return React.DOM.div(null, Label({text: "Hello"}));
    }
});

编译器会检查 Label 是用 text 属性调用的,并且它是一个字符串。

下一步是让编译器检查this.props.text 使用内部 Label 方法。怎么做?

【问题讨论】:

    标签: typescript reactjs


    【解决方案1】:

    本质上,您想为 Props 和 State 创建接口,并将它们作为扩展 React.Component 的新类的类型传递。使用 React 类型定义意味着您不必为除了您正在创建的新类之外的任何东西添加类型。您可以在下面的模式中看到这一点。

    (我写了一篇关于这个here的博文)

    /// <reference path='../typings/react/react.d.ts' />
    import React = require('react');
    
    interface P {
      name?: string;
    }
    
    interface S {
      complete?: boolean;
    }
    
    class Goal extends React.Component<P, S> {
      state: S = {
        complete: false
      }
    
      private _toggleCompletion = () => {
        this.setState({complete: !this.state.complete});
      }
    
      render() {
        var status = 'Status: ' + (this.state.complete ? 'complete' : 'incomplete');
        return React.DOM.div({
          children: [
            React.DOM.div({}, this.props.name + ' - ' + status),
            React.DOM.button({
              onClick: this._toggleCompletion
            }, 'Toggle completion')
          ]
        });
      }
    }
    
    React.render(React.createElement(Goal, {name: 'Learn React and TypeScript'}), document.getElementById('react'));
    

    【讨论】:

      【解决方案2】:

      我使用react-typescript 桥接器,它定义了一个可以从 TypeScript 使用的基类:

      class HelloMessage extends ReactTypescript.ReactComponentBase<{ name: string; }, {}> {
        render() {
          return React.DOM.div(null, 'Hello ' + this.props.name);
        }
      }
      

      由于基类是通用的,this.props 在上面的示例中被正确地键入为{ name: string; }

      【讨论】:

      • 过去有一个错误导致我在 Chrome 中使用 React 调试工具时以及从其他 ReactComponentBase 组件的 render 方法返回 ReactComponentBase 组件时出现问题,但我还没有解决提交这些修复...如果您对最新版本有任何问题,我可以挖掘出我所做的更改。
      • 经过更多测试,componentDidMount 不起作用。您是否看到相同的行为?
      • 不,没有看到,我用它来连接窗口调整大小处理程序。如果正在调用渲染,我希望也会调用其他覆盖。
      • 警告任何来到这篇文章的新人 - 这个答案真的,真的过时了。
      猜你喜欢
      • 2021-06-18
      • 1970-01-01
      • 2021-07-25
      • 2021-12-29
      • 2017-04-05
      • 2019-11-29
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      相关资源
      最近更新 更多