#javascript #reactjs #react-dnd
Вопрос:
Мне нужна возможность иметь два одинаковых элемента, в то время как они не дублируются при перетаскивании на доску. Но когда я перетаскиваю элемент, существующий на доске, он регистрирует «перемещение».
Вместо этого он должен добавить другой одноименный элемент с другим ключом. Мне трудно найти свою ошибку, пожалуйста, помогите.
Это мой код
import { React, useState } from "react";
import { useDrop } from "react-dnd";
import { ItemTypes } from "../ItemTypes";
import Items from "./Items";
const Board = () => {
const [components, setComponents] = useState([]);
const onDelete = (id) => {
console.log(components);
console.log(id);
setComponents(components.filter((component) => component.key !== id));
};
const [, drop] = useDrop(() => ({
accept: ItemTypes.COMPONENT,
drop: (item) => {
console.log(item.name, item.key);
if (item.key === undefined) {
const { nanoid } = require("nanoid");
const itemKey = { key: nanoid(16) };
const newItem = Object.assign(item, itemKey);
setComponents((components) => [...components, newItem]);
console.log("add");
} else {
console.log("moving");
}
},
}));
return (
<div ref={drop} className="board">
<Items components={components} onDelete={onDelete} />
</div>
);
};
export default Board;
это компонент(внешний, должен преобразовываться в элемент при перетаскивании)
import React from "react";
import { useDrag } from "react-dnd";
import { ItemTypes } from "../ItemTypes";
const Component = ({ component }) => {
const [, drag] = useDrag(
() => ({
type: ItemTypes.COMPONENT,
item: component,
}),
[]
);
return (
<div ref={drag} className="component">
<h4>{component.name}</h4>
</div>
);
};
export default Component;
Это пункт(на текущей доске)
import React from "react";
import { useDrag } from "react-dnd";
import { ItemTypes } from "../ItemTypes";
import { FaTimes } from "react-icons/fa";
const Item = ({ component, onDelete, key, left, top }) => {
const [{ isDragging }, drag] = useDrag(
() => ({
type: ItemTypes.COMPONENT,
item: component,
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
}),
[key, left, top]
);
if (isDragging) {
return <div ref={drag} />;
}
return (
<div ref={drag} className="item">
<h4>
{component.name}
{<FaTimes onClick={() => onDelete(component.key)} />}
</h4>
</div>
);
};
export default Item;
Комментарии:
1. Можете ли вы добавить свою логику перетаскивания? Кроме того, ваш компонент, в котором вы создаете ключ
2. генератор ключей находится в блоке if
3. В консоли drop добавьте еще одно свойство, чтобы увидеть, какое значение вы получаете
console.log(item.name, item.key, typeof item.key);
. Если тип item.key не определен, он перейдет в ваш блок else. Как правило, вы можете изменить свое состояние наif (item.key)
вместо того, чтобы проверятьundefined
.4. Я сменил его на
if(!item.key)
, но все осталось по-прежнему. Я не могу понять, почемуcomponent
у меня есть ключ отitem
.5.
const newItem = Object.assign(item, itemKey);
измените это наconst newItem = Object.assign({},item, itemKey);
Ответ №1:
Итак, проблема в том, как мы Object.Assign()
правильно используем. Он выполняет по крайней мере 2 работы.
- Обновляет существующий объект.
Object.assign(item, itemKey);
обновляет ключ элемента. - Создает новый объект
Object.assign({},item, itemKey);
Это создает совершенно новый объект, поскольку он объединяет старые свойства с пустым объектом.
Вместо этого вы могли бы использовать оператор распространения, чтобы избежать путаницы. const newItem = {...item, itemKey};
это бы сработало.