我正在嘗試讓這個 beautiful-react-dnd 示例正常作業,但目前我遇到了一些錯誤:
import * as React from 'react';
import {
DragDropContext,
Draggable,
Droppable,
DroppableProvided,
DraggableLocation,
DropResult,
DroppableStateSnapshot, DraggableProvided, DraggableStateSnapshot
} from 'react-beautiful-dnd';
import {Flex} from 'grid-styled'
import './App.css';
interface Item {
id: string;
content: string;
}
interface IAppState {
items: Item[];
selected: Item[];
}
interface IMoveResult {
droppable: Item[];
droppable2: Item[];
}
const getItems = (count: number, offset:number = 0): Item[] => {
return Array
.from({length: count}, (v, k) => k)
.map(k => ({
content: `item ${k offset}`,
id: `item-${k offset}`
}));
};
const reorder = (list: Item[], startIndex: number, endIndex: number):Item[] => {
const result = [...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: Item[], destination: Item[], droppableSource:DraggableLocation, droppableDestination:DraggableLocation):IMoveResult | any => {
const sourceClone = [...source];
const destClone = [...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:number = 8;
const getItemStyle = (draggableStyle: any, isDragging: boolean):{} => ({
userSelect: 'none',
padding: 2*grid,
margin: `0 0 ${grid}px 0`,
background: isDragging ? 'lightgreen' : 'grey',
...draggableStyle
});
const getListStyle = (isDraggingOver: boolean):{} => ({
background: isDraggingOver ? 'lightblue' : 'lightgrey',
padding: grid,
width: 300,
minHeight: 400
});
export default class App extends React.Component<{}, IAppState> {
public id2List = {
droppable: 'items',
droppable2: 'selected'
};
constructor(props:any) {
super(props);
this.state = {
items: getItems(10, 0),
selected: getItems(5, 10)
};
this.onDragEnd = this.onDragEnd.bind(this);
this.getList = this.getList.bind(this);
}
public getList (id:string):Item[] {
return this.state[this.id2List[id]];
}
public onDragEnd(result: DropResult):void {
const { source, destination } = result;
if (!destination) {
return;
}
if (source.droppableId === destination.droppableId) {
const items = reorder(
this.getList(source.droppableId),
source.index,
destination.index
);
let state:IAppState = {...this.state};
if (source.droppableId === "droppable2") {
state = { ...this.state, selected: items };
} else if (source.droppableId === "droppable") {
state = {...this.state, items}
}
this.setState(state);
} else {
const resultFromMove:IMoveResult = move(
this.getList(source.droppableId),
this.getList(destination.droppableId),
source,
destination
);
this.setState({
items: resultFromMove.droppable,
selected: resultFromMove.droppable2
});
}
}
public render() {
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Flex justifyContent={"space-between"}>
<Flex flexDirection="column">
<Droppable droppableId="droppable">
{(provided:DroppableProvided, snapshot:DroppableStateSnapshot) => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
style={getListStyle(snapshot.isDraggingOver)}
>
{this.state.items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(providedDraggable:DraggableProvided, snapshotDraggable:DraggableStateSnapshot) => (
<div>
<div
ref={providedDraggable.innerRef}
{...providedDraggable.draggableProps}
{...providedDraggable.dragHandleProps}
style={getItemStyle(
providedDraggable.draggableProps.style,
snapshotDraggable.isDragging
)}
>
{item.content}
</div>
{providedDraggable.placeholder}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</Flex>
<Droppable droppableId="droppable2">
{(providedDroppable2:DroppableProvided, snapshotDroppable2:DroppableStateSnapshot) => (
<div
ref={providedDroppable2.innerRef}
style={getListStyle(snapshotDroppable2.isDraggingOver)}>
{this.state.selected.map((item, index) => (
<Draggable
key={item.id}
draggableId={item.id}
index={index}>
{(providedDraggable2:DraggableProvided, snapshotDraggable2:DraggableStateSnapshot) => (
<div>
<div
ref={providedDraggable2.innerRef}
{...providedDraggable2.draggableProps}
{...providedDraggable2.dragHandleProps}
style={getItemStyle(
providedDraggable2.draggableProps.style,
snapshotDraggable2.isDragging
)}>
{item.content}
</div>
{providedDraggable2.placeholder}
</div>
)}
</Draggable>
))}
{providedDroppable2.placeholder}
</div>
)}
</Droppable>
</Flex>
</DragDropContext>
);
}
}
參考:https : //github.com/abeaudoin2013/react-beautiful-dnd-multi-list-typescript-example/blob/master/src/App.tsx
目前我在嘗試運行此示例時看到的 2 個錯誤:
錯誤#1 元素隱式具有“any”型別,因為“string”型別的運算式不能用于索引型別“{}”。在型別“{}”上找不到帶有“字串”型別引數的索引簽名。TS7053
結果[droppableSource.droppableId] = sourceClone;
錯誤#2 元素隱式具有“any”型別,因為“any”型別的運算式不能用于索引“Readonly”型別。TS7053
public getList(id: string): Item[] {
99 | 回傳 this.state[this.id2List[id]]; | ^ 100 | }
這是我的依賴項:
"dependencies": {
"@reduxjs/toolkit": "^1.5.1",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@types/jest": "^24.0.0",
"@types/node": "^12.0.0",
"@types/react": "^16.9.0",
"@types/react-beautiful-dnd": "^13.1.2",
"@types/react-dom": "^16.9.0",
"@types/react-redux": "^7.1.7",
"@types/react-router-dom": "^5.3.2",
"react": "^17.0.2",
"react-beautiful-dnd": "^13.1.0",
"react-dom": "^17.0.2",
"react-redux": "^7.2.0",
"react-router-dom": "^6.0.2",
"react-scripts": "4.0.3",
"typescript": "~4.1.5"
},
uj5u.com熱心網友回復:
如果使用 TypeScript,則必須為變數提供型別。否則型別檢查根本沒有幫助。
const result : { [key:string]:Item[]; } = {};
應該解決第一個問題。我沒有嘗試代碼,如果它不起作用我會更正它。
這個構造也是如此:
public id2List = {
droppable: 'items',
droppable2: 'selected'
}; // <-- what is the type here?
我想應該是
public id2List = {
droppable: 'items',
droppable2: 'selected'
} as { [key:string]: keyof IAppState; };
要了解有關這些型別的更多資訊,您可以查看TypeScript 中的索引簽名概念。此外,如果您可以避免它們并在型別中使用正確的屬性名稱,那么最好這樣做,因為縮小型別可以使您的代碼不易出錯。
因為 App 組件是一個引數化的類,所以它IAppState作為this.state. 要將id2List值與 中的屬性名稱聯系起來IAppState,使用了keyof運算子。
值得一提的是,如果您不能或不想弄清楚正確的型別,您還可以明確地將“any”宣告為一種型別。也就是說const result: any = {};,編譯器可能仍然可以接受,具體取決于設定。但它也無視任何理由首先使用 TS。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/369133.html
上一篇:回傳一個可觀察的正確
