【问题标题】:How to attach drag event handlers to a React component using TypeScript如何使用 TypeScript 将拖动事件处理程序附加到 React 组件
【发布时间】:2017-09-05 21:37:33
【问题描述】:

我正在使用 TypeScript (2.4.2) 首次涉足 React (15.6.1),并且我正在尝试创建一个表示可拖动的 JSON 字段的组件。这是我的组件代码:

import * as React from "react";

interface JsonFieldProps {
    name: string;
    type: string;
    indent: number;
}

export class JsonField extends React.Component<JsonFieldProps, undefined> {
    marginStyle = {
        'text-indent': `${this.props.indent * 15}px`
    };

    render() {
        return <div draggable={true} onDragStart={handleDrag} style={this.marginStyle}>{this.props.name}: {this.props.type},</div>;
    }
}

function handleDrag(ev: DragEvent): void {
    let id = (ev.target as HTMLDivElement).id;
    ev.dataTransfer.setData("text/plain", id);
}

当我尝试编译它(使用 webpack)时,我收到以下错误:

ERROR in [at-loader] ./src/components/JsonField.tsx:15:21 
  TS2322: Type '{ draggable: true; onDragStart: (ev: DragEvent) => void;
    style: { 'text-indent': string; }; child...' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
  Type '{ draggable: true; onDragStart: (ev: DragEvent) => void; style: { 'text-indent': string; }; child...' is not assignable to type 'HTMLAttributes<HTMLDivElement>'.
    Types of property 'onDragStart' are incompatible.
      Type '(ev: DragEvent) => void' is not assignable to type 'EventHandler<DragEvent<HTMLDivElement>>'.
        Types of parameters 'ev' and 'event' are incompatible.
          Type 'DragEvent<HTMLDivElement>' is not assignable to type 'DragEvent'.
            Property 'initDragEvent' is missing in type 'DragEvent<HTMLDivElement>'.

我不确定我是否使用了错误的事件类型,但如果是错误的,我似乎找不到任何关于哪个是正确的信息。

【问题讨论】:

  • Facebook 制作了flow,它可能与 React 配合得更好,请参阅 this too

标签: javascript reactjs typescript


【解决方案1】:

您必须使用React.DragEvent 接口而不是通用DOM DragEvent

export class JsonField extends React.Component<JsonFieldProps, undefined>
{
    private marginStyle = {
        textIndent: `${this.props.indent * 15}px`
    };

    public render()
    {
        return (
            <div
                draggable={true}
                onDragStart={handleDrag}
                style={this.marginStyle}>
                {this.props.name}: {this.props.type}
            </div>);
    }
}

function handleDrag(ev: React.DragEvent<HTMLDivElement>): void
{
    const id = (ev.target as HTMLDivElement).id;
    ev.dataTransfer.setData("text/plain", id);
}

还要注意将 text-indent 更改为 textIndent,因为您使用的是 react 而不是纯 html。请记住,在 react 中您主要使用虚拟 DOM,而不是真实的 DOM - 因此所有这些更改。

作为旁注,我建议您将事件处理程序保留在类内而不是类外。这样您就可以访问类实例的属性和方法。

【讨论】:

  • 谢谢,成功了。需要注意的是 IntelliJ 无法识别导出。 TS2694: Namespace 'React' has no exported member 'DragEvent'. 知道如何解决这个问题吗?
  • 很遗憾,我没有使用 IntelliJ 的经验。造成这种情况的常见原因是 react 的 typescript 定义丢失或过时。尝试安装他们的最新版本。你也可以查看这个帖子:intellij-support.jetbrains.com/hc/en-us/community/posts/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多