6

我读到一些用户提到他们正在使用这个支持 Typescript 的库,但是我在任何地方都找不到任何文档,我似乎也无法让它自己工作。

我正在使用 typescript 2,我无法创建一个非常简单的工作示例,只允许我拖动现有组件。我尝试了几种可能性,但在调用 DragSource(作为装饰器或函数)或渲染生成的组件时,我总是遇到一些打字问题。

简而言之,我想要一个示例,显示在 typescript 中使用 react-dnd,它允许我如何使现有组件可拖动,可能无需修改组件本身(它不应该知道它是可拖动的)

感谢您的任何帮助!

4

1 回答 1

14

我已经让它与 2.1 上的 DT types 包一起使用。它不能用 strictNullChecks 编译,我也无法找到原因。(当你用@DragSource 和@DropTarget 装饰你的组件时,你以某种方式将渲染函数的返回类型从Element 更改为Element | null,但我不知道如何。)

另一个小问题是,当您第一次在渲染方法中实例化组件时,收集函数插入的所有道具都是未定义的,因此您的选择是传递一堆{undefined as any}或者将您的收集器注入的道具声明为可选项和类型保护他们在你看到的每一个地方。总体而言,类型声明文件还不错,我发现在了解库时,键入比有害更有用。

import { 
    ConnectDragSource,
    DragDropContext, 
    DragSource, 
    DragSourceSpec, 
    DragSourceCollector, 
    DragSourceConnector, 
    DragSourceMonitor, 
    DragElementWrapper,
    ConnectDropTarget,
    DropTarget,
    DropTargetConnector,
    DropTargetMonitor,
    ClientOffset,
    DropTargetSpec } from 'react-dnd';
let HTML5Backend = require('react-dnd-html5-backend');
import { AdjacencyMatrixGraph } from "Geometry/Graph";

import * as React from "react";
import * as Sauce from "Sauce";
import * as ReactDOM from "react-dom";
import * as $ from "jquery";
import { Position2 } from "Geometry";
import * as Rx from "rxjs";
import * as Util from "Util";
require("./GraphBuilder.scss");

interface NodeProps {
  label?: string;
  position: ClientOffset;
}

/* New node from the node well */
export interface NodeSourceProps {
   isDragging : boolean;
   connectDragSource: ConnectDragSource;
}
export interface NodeSourceState {
}

// Spec: drag events to handle.
let nodeSourceSpec: DragSourceSpec<NodeSourceProps> = {
    beginDrag: (props: NodeSourceProps) => ({}),
};

// Collect: Put drag state into props
let nodeSourceCollector = (connect: DragSourceConnector, monitor: DragSourceMonitor) => {
    return {
      connectDragSource: connect.dragSource(),
      isDragging: monitor.isDragging()
  }
};

@DragSource("new-node", nodeSourceSpec, nodeSourceCollector)
export class NodeSource extends React.Component<NodeSourceProps, NodeSourceState> {
  constructor(props: NodeSourceProps) {
    super(props);
  }
  render() {
    const { connectDragSource, isDragging } = this.props;
    return connectDragSource(<span className="node-source">{'\u2683'}</span>);
  }
}

/* main graph area */
interface GraphCanvasProps {
    connectDropTarget: ConnectDropTarget,
    isOver: boolean,
    graph: AdjacencyMatrixGraph<NodeProps>;
}

interface GraphCanvasState {}
const canvasDropTargetSpecification: DropTargetSpec<GraphCanvasProps> = {
  drop(props: GraphCanvasProps, monitor: DropTargetMonitor, component: React.Component<GraphCanvasProps, any>) {
    // console.log("Handling drop", print_monitor(monitor));
    let pos = monitor.getSourceClientOffset();
    if (monitor.getItemType() === "main-node-move") {
      let node = (monitor.getItem() as any);
      graph.setData(node.id, { position: pos });
    }
    else if (monitor.getItemType() === "new-node") {
      graph.addNode("node-" + graph.order(), { position: pos });
    }
  },
};

function canvasDropTargetCollectingFunction(connect: DropTargetConnector, monitor: DropTargetMonitor) {
  let rv = {
    connectDropTarget: connect.dropTarget(),
    isOver: monitor.isOver(),
  };

  return rv;
}
/* ... here's  a DropTarget ... */

@DropTarget(["main-node-move", "new-node"], canvasDropTargetSpecification, canvasDropTargetCollectingFunction)
export class GraphCanvas extends React.Component<GraphCanvasProps, GraphCanvasState> {
  constructor(props: GraphCanvasProps) {
    super(props);
  }

  render(): JSX.Element | null {
    const { connectDropTarget, graph } = this.props;
    let nodes = graph.nodes();
    let nodeEls = Object.keys(nodes).map(k => {
      let node = nodes[k];
      return <CanvasNode 
      key={k} 
      id={k} 
      node={node} 
      graph={graph} 
      connectNodeDrop={null as any} 
      connectMoveNodeDragger={(null)}/>
    });
    return connectDropTarget(<div className="graph-canvas">
      {nodeEls}
    </div>);
  }
}

/* ... Here's a the DragContext decorator ... */

@DragDropContext(HTML5Backend)
class Markov extends React.Component<MarkovProps, MarkovState>  {
于 2016-12-16T02:16:21.827 回答