javascript - 如何在不手动重建的情况下复制和渲染 React 元素?
问题描述
我正在尝试创建一个非常简单的拖放组件,并且我认为只需通过onDrop
事件构建一个数组,只需将其添加event.target
就足够了,但似乎 React 不喜欢这样。它在渲染时给我错误“对象作为 React 子项无效”,如果我在添加到数组之前尝试克隆元素,我会得到“元素类型无效:需要一个字符串(对于内置组件)或类/函数(用于复合组件)但得到:未定义”。
我四处搜索,几乎我一直看到的类似问题的唯一建议是基本上用最初使用的任何道具重建元素。如果元素类型/道具/等是已知的并且总是相同的,这一切都很好,但如果不是呢?是否有更灵活的解决方案来复制您可能不知道它最初是如何构造的元素?
这是我的代码现在的样子:
import React from 'react'
import ReactDOM from 'react-dom'
function Draggable(props) {
return <div draggable={true} onDragStart={props.onDragStart}>{props.children}</div>
}
function Droppable(props) {
return <div onDragOver={props.onDragOver} onDrop={props.onDrop} className="droppable">{props.children}</div>
}
export default function App() {
const [draggedElement, setDraggedElement] = React.useState(null)
const [droppedElements, setDroppedElements] = React.useState([])
function onDragStart(e) {
setDraggedElement(e.target);
}
function onDragOver(e) {
e.preventDefault();
}
function onDrop(e) {
e.preventDefault();
setDroppedElements([...droppedElements, React.cloneElement(draggedElement, {key: 'test'})]);
}
return (
<React.Fragment>
<Draggable onDragStart={onDragStart}>draggable</Draggable>
<Droppable onDragOver={onDragOver} onDrop={onDrop}>{droppedElements}</Droppable>
</React.Fragment>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
解决方案
您可以使用 e.dataTransfer.setData() 和 e.dataTransfer.getData() 来更好地传输数据。这是我使用可拖动卡片组件所做的项目示例:
const dragStart = e => {
// e.preventDefault();
console.log("in dragStart");
const target = e.target;
e.dataTransfer.setData('card_id', target.id);
const drop = e => {
console.log("Here in first drop function");
e.preventDefault();
const card_id = e.dataTransfer.getData('card_id');
const card = document.getElementById(card_id);
然后将卡片放到某个东西上,在 drop 函数中,您可以使用 e.target.append() 将从 e.dataTransfer.getData 元素中获得的数据放到 e.target 中。
e.target.appendChild(card);
所以在这种情况下,e.target.appendChild(card) 中的“卡片”只是使用 e.dataTransfer.setData() 在 dragStart 函数中设置的数据。如果这是有道理的。
推荐阅读
- reactjs - 如何检查 react-360 代码已在 npm 上更新
- ruby-on-rails - 如何在 ActiveRecord 中订购累计付款?
- scala - 在 Scala.js 中轮询未来
- javascript - 如何动态生成 Bootstrap DatePicker datesDisabled
- java - 我可以应用哪些模式来避免方法重载此类中的所有方法?
- reactjs - 我们如何跨存储库共享 React 组件
- python - PySpark:将时间戳添加到日期列并将整个列重新格式化为时间戳数据类型
- firebase - 文档或集合的人类可读键
- javascript - react 钩子中的 useEffect 执行顺序及其内部清理逻辑是什么?
- python - Pandas 中的聚合