React dnd broad 不适用于打字稿

React dnd broad not working on the typescript

我尝试在 React typescript 上使用这个 react dnd。示例无法在 type script 项目上工作,任何人都知道如何在 react typescript 上正确地做到这一点

import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

    // fake data generator
    const getItems = (count, offset = 0) =>
      Array.from({ length: count }, (v, k) => k).map(k => ({
        id: `item-${k + offset}`,
        content: `Item: ${k + offset}, Random value: ${Math.round(Math.random() * 100)}`,
        color: Math.random () > 0.66 ? 'pink': Math.random() > 0.5 ? 'lightgreen' : 'beige'
      }))

    // a little function to help us with reordering the result
    const reorder = (list, startIndex, endIndex) => {
      const result = Array.from(list)
      const [removed] = result.splice(startIndex, 1)
      result.splice(endIndex, 0, removed)
      return result
    }

    /**
     * Moves an item from one list to another list.
     */
    const move = (source, destination, droppableSource, droppableDestination) => {
      const sourceClone = Array.from(source)
      const destClone = Array.from(destination)
      const [removed] = sourceClone.splice(droppableSource.index, 1)

      destClone.splice(droppableDestination.index, 0, removed)

      const result = {}
      result[droppableSource.droppableId] = sourceClone
      result[droppableDestination.droppableId] = destClone

      return result
    }

    const grid = 4

    const getItemStyle = (isDragging, draggableStyle) => ({
      // some basic styles to make the items look a bit nicer
      userSelect: 'none',
      padding: grid * 2,
      margin: `0 0 ${grid}px 0`,

      // change background colour if dragging
      background: isDragging ? 'lightgreen' : 'lightgrey',

      // styles we need to apply on draggables
      ...draggableStyle
    })

    const getListStyle = isDraggingOver => ({
      background: isDraggingOver ? 'lightblue' : '#eee',
      padding: grid,
      margin: '3px',
      width: 250
    })

    class App extends Component {
      state = {
        list1: getItems(5,1),
        list2: getItems(4, 6),
        list3: getItems(6, 10)
      }

      /**
       * A semi-generic way to handle multiple lists. Matches
       * the IDs of the droppable container to the names of the
       * source arrays stored in the state.
       */
      droppableIds = {
        droppable1: 'list1',
        droppable2: 'list2',
        droppable3: 'list3'
      }

      getList = id => this.state[this.droppableIds[id]]

      onDragEnd = result => {
        const { source, destination } = result

        // dropped outside the list
        if (!destination) { return }

        if (source.droppableId === destination.droppableId) {
          const items = reorder(
            this.getList(source.droppableId),
            source.index,
            destination.index
          )

          let copiedState = Object.assign({}, this.state)

          if (source.droppableId === 'droppable1') {
            copiedState.list1 = items
          } else if (source.droppableId === 'droppable2') {
            copiedState.list2 = items
          } else if (source.droppableId === 'droppable3') {
            copiedState.list3 = items
          }

          this.setState(copiedState)
        } else {
          const result = move(
            this.getList(source.droppableId),
            this.getList(destination.droppableId),
            source,
            destination
          )

          console.warn('result', result)
          this.setState({
            list1: result.droppable1 ? result.droppable1 : this.state.list1,
            list2: result.droppable2 ? result.droppable2 : this.state.list2,
            list3: result.droppable3 ? result.droppable3 : this.state.list3
          })
        }
      }

      // Normally you would want to split things out into separate components.
      // But in this example everything is just done in one place for simplicity
      render() {
        const lists = [
          {
            droppableId: 'droppable1',
            listId: 'list1',
            title: 'List A'
          },
          {
            droppableId: 'droppable2',
            listId: 'list2',
            title: 'List B'
          },
          {
            droppableId: 'droppable3',
            listId: 'list3',
            title: 'List C'
          },
        ]
        return (
          <div style={{ display: 'flex' }}>
            <DragDropContext onDragEnd={this.onDragEnd}>

              {lists.map((list, listIndex) =>
                <Droppable key={'list-droppable-' + listIndex} droppableId={list.droppableId}>
                  {(provided, snapshot) => (
                    <div
                      ref={provided.innerRef}
                      style={getListStyle(snapshot.isDraggingOver)}>
                      <h4>
                        {list.title}
                      </h4>
                      {this.state[list.listId] && this.state[list.listId].map((item, index) => (
                        <Draggable
                          key={item.id}
                          draggableId={item.id}
                          index={index}>
                          {(provided, snapshot) => (
                            <div
                              ref={provided.innerRef}
                              { ...provided.draggableProps }
                              { ...provided.dragHandleProps }
                              style={getItemStyle(
                                snapshot.isDragging,
                                provided.draggableProps.style
                              )}>
                              <div style={{ background: item.color }}>
                                {item.content}
                              </div>
                            </div>
                          )}
                        </Draggable>
                      ))}
                      {provided.placeholder}
                    </div>
                  )}
                </Droppable>
              )}
            </DragDropContext>
          </div>
        )
      }
    }

    // Put the things into the DOM!
    ReactDOM.render(<App />, document.getElementById('root'));

尝试这样的事情。

import React, { Component } from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";

// fake data generator
const getItems = (count: number, offset: number): object =>
  Array.from({ length: count }, (v, k): number => k).map(
    (k: number): {} => ({
      id: `item-${k + offset}`,
      content: `Item: ${k + offset}, Random value: ${Math.round(
        Math.random() * 100
      )}`,
      color:
        Math.random() > 0.66
          ? "pink"
          : Math.random() > 0.5
          ? "lightgreen"
          : "beige"
    })
  );

// a little function to help us with reordering the result
const reorder = (list: [], startIndex: number, endIndex: number): object => {
  const result = Array.from(list);
  const [removed] = result.splice(startIndex, 1);
  result.splice(endIndex, 0, removed);
  return result;
};

/**
 * Moves an item from one list to another list.
 */
const move = (
  source: any,
  destination: any,
  droppableSource: any,
  droppableDestination: any
): {} => {
  const sourceClone = Array.from(source);
  const destClone = Array.from(destination);
  const [removed] = sourceClone.splice(droppableSource.index, 1);

  destClone.splice(droppableDestination.index, 0, removed);

  let result: any = {};
  result[droppableSource.droppableId] = sourceClone;
  result[droppableDestination.droppableId] = destClone;

  return result;
};

const grid = 4;

const getItemStyle = (isDragging: boolean, draggableStyle: any): object => ({
  // some basic styles to make the items look a bit nicer
  userSelect: "none",
  padding: grid * 2,
  margin: `0 0 ${grid}px 0`,

  // change background colour if dragging
  background: isDragging ? "lightgreen" : "lightgrey",

  // styles we need to apply on draggables
  ...draggableStyle
});

const getListStyle = (isDraggingOver: boolean): object => ({
  background: isDraggingOver ? "lightblue" : "#eee",
  padding: grid,
  margin: "3px",
  width: 250
});

interface State {
  list1: object;
  list2: object;
  list3: object;
}

class App extends Component<State> {
  state: State = {
    list1: getItems(5, 1),
    list2: getItems(4, 6),
    list3: getItems(6, 10)
  };

  /**
   * A semi-generic way to handle multiple lists. Matches
   * the IDs of the droppable container to the names of the
   * source arrays stored in the state.
   */
  droppableIds = {
    droppable1: "list1",
    droppable2: "list2",
    droppable3: "list3"
  };

  getList = (id: string): any => this.state[this.droppableIds[id]];

  onDragEnd = (result: any) => {
    const { source, destination } = result;

    // dropped outside the list
    if (!destination) {
      return;
    }

    if (source.droppableId === destination.droppableId) {
      const items: object = reorder(
        this.getList(source.droppableId),
        source.index,
        destination.index
      );

      let copiedState: any = Object.assign({}, this.state);

      if (source.droppableId === "droppable1") {
        copiedState.list1 = items;
      } else if (source.droppableId === "droppable2") {
        copiedState.list2 = items;
      } else if (source.droppableId === "droppable3") {
        copiedState.list3 = items;
      }

      this.setState(copiedState);
    } else {
      const result: any = move(
        this.getList(source.droppableId),
        this.getList(destination.droppableId),
        source,
        destination
      );

      this.setState({
        list1: result.droppable1 ? result.droppable1 : this.state.list1,
        list2: result.droppable2 ? result.droppable2 : this.state.list2,
        list3: result.droppable3 ? result.droppable3 : this.state.list3
      });
    }
  };
  render() {
    const lists = [
      {
        droppableId: "droppable1",
        listId: "list1",
        title: "List A"
      },
      {
        droppableId: "droppable2",
        listId: "list2",
        title: "List B"
      },
      {
        droppableId: "droppable3",
        listId: "list3",
        title: "List C"
      }
    ];
    return (
      <div style={{ display: "flex" }}>
        <DragDropContext onDragEnd={this.onDragEnd}>
          {lists.map((list, listIndex) => (
            <Droppable
              key={"list-droppable-" + listIndex}
              droppableId={list.droppableId}
            >
              {(provided: any, snapshot: any) => (
                <div
                  ref={provided.innerRef}
                  style={getListStyle(snapshot.isDraggingOver)}
                >
                  <h4>{list.title}</h4>
                  {this.state[list.listId] &&
                    this.state[list.listId].map((item: any, index: number) => (
                      <Draggable
                        key={item.id}
                        draggableId={item.id}
                        index={index}
                      >
                        {(provided: any, snapshot: any) => (
                          <div
                            ref={provided.innerRef}
                            {...provided.draggableProps}
                            {...provided.dragHandleProps}
                            style={getItemStyle(
                              snapshot.isDragging,
                              provided.draggableProps.style
                            )}
                          >
                            <div style={{ background: item.color }}>
                              {item.content}
                            </div>
                          </div>
                        )}
                      </Draggable>
                    ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
          ))}
        </DragDropContext>
      </div>
    );
  }
}

export default App;

这是一个工作示例codesandox