arrays - 使用 react-dnd beautiful 如何将新项目插入数组,或者它不起作用?
问题描述
在我的项目中,我试图将我的信息更改为 react-dnd 漂亮的拖放。
但是当我改变它时,拖放不适用于插入到数组中的新项目。
我如何使它在这个例子中仍然有效?
import React, { useState } 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}-${new Date().getTime()}`,
content: `item ${k + offset}`
}));
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 = 8;
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" : "grey",
// styles we need to apply on draggables
...draggableStyle
});
const getListStyle = (isDraggingOver) => ({
background: isDraggingOver ? "lightblue" : "lightgrey",
padding: grid,
width: 250
});
function QuoteApp() {
const [state, setState] = useState([getItems(10), getItems(5, 10)]);
function onDragEnd(result) {
const { source, destination } = result;
// dropped outside the list
if (!destination) {
return;
}
const sInd = +source.droppableId;
const dInd = +destination.droppableId;
if (sInd === dInd) {
const items = reorder(state[sInd], source.index, destination.index);
const newState = [...state];
newState[sInd] = items;
setState(newState);
} else {
const result = move(state[sInd], state[dInd], source, destination);
const newState = [...state];
newState[sInd] = result[sInd];
newState[dInd] = result[dInd];
setState(newState.filter((group) => group.length));
}
}
return (
<div>
<button
type="button"
onClick={() => {
setState([...state, []]);
}}
>
Add new group
</button>
<button
type="button"
onClick={() => {
setState([...state, getItems(1)]);
}}
>
Add new item
</button>
<div style={{ display: "flex" }}>
<DragDropContext onDragEnd={onDragEnd}>
{state.map((el, ind) => (
<Droppable key={ind} droppableId={`${ind}`}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
style={getListStyle(snapshot.isDraggingOver)}
{...provided.droppableProps}
>
{el.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={{
display: "flex",
justifyContent: "space-around"
}}
>
ind:{ind} , index{index} ,{item.content}
<button
type="button"
onClick={() => {
const newState = [...state];
newState[ind].splice(index, 1);
setState(
newState.filter((group) => group.length)
);
}}
>
delete
</button>
<button
type="button"
onClick={() => {
const newState = [...state];
newState[ind].splice(
index,
0,
getItems(1, index)
);
setState(
newState.filter((group) => group.length)
);
}}
>
add s/o
</button>
</div>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
))}
</DragDropContext>
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<QuoteApp />, rootElement);
具体变化是“add s/o”按钮
感谢您的时间
解决方案
问题
当您插入/添加一个“s/o”(对不起,不确定那是什么)时,您拼接的返回值getItems
是一个数组,但您的主要状态形状是一个对象数组。
const getItems = (count, offset = 0) =>
Array.from({ length: count }, (v, k) => k).map((k) => ({
id: `item-${k + offset}-${new Date().getTime()}`,
content: `item ${k + offset}`
}));
...
<button
type="button"
onClick={() => {
const newState = [...state];
newState[ind].splice(
index,
0,
getItems(1, index) // <-- inserts array!!
);
setState(
newState.filter((group) => group.length)
);
}}
>
add s/o
</button>
您插入了一个数组而不是对象。
{newState: Array(2)}
newState: Array(2)
0: Array(11)
0: Array(1) // <-- inserted array
0: Object // <-- object you want inserted
id: "item-0-1609711045911"
content: "item 0"
1: Object
id: "item-0-1609711042837"
content: "item 0"
2: Object
3: Object
4: Object
5: Object
6: Object
7: Object
8: Object
9: Object
10: Object
1: Array(5)
解决方案
似乎一个相当简单的解决方案是getItems
在拼接新的“s/o”时弹出单个插入的对象。
<button
type="button"
onClick={() => {
const newState = [...state];
newState[ind].splice(
index,
0,
getItems(1, index).pop(), // <-- pop value from array
);
setState(
newState.filter((group) => group.length)
);
}}
>
add s/o
</button>
推荐阅读
- c++ - Recvfrom 函数没有接收到数据
- c# - C# - 运行选定的代码生成器时出错:无法获取 DbContext 的反射类型
- django - 向 DRF 通用列表视图添加字段
- python - 如何更改 tkinter 中输入文本的颜色?
- json - 如何在 JSON 文件中用空字符串替换匹配的字符串?
- database - 访问不想打开报告 - 不关注其他窗口
- algorithm - 如何在遗传算法中进行二进制编码以获得更好的时间表调度问题结果?
- c++ - 如果进程正在运行,我如何关闭我的程序?
- python - KerasLayer 模型经过微调后尺寸增大
- python - 使用 Pyinstaller 创建的 .exe 文件显示错误 input(): lost sys.stdin