我正在使用React构建一个拖放应用程序,并遵循本教程:https://jsfiddle.net/xv5mu40h/8/。
然而,当我在我的终端尝试它时,我会得到这样的错误消息:TypeError: Cannot read property 'cloneNode' of null,特别提到了这一行代码:const nodeCopy = document.getElementById(data).cloneNode(true);。
我已经在这行代码之前记录了data是什么,当我试图拖放任何对象(在本例中称为奖励)时,data似乎是空的。任何帮助都是非常感谢的!
注意:我已经尽可能多地提取了不相关的代码;对于更多的焦点,我认为问题在于拖放函数(而不是任何生命周期方法或唯一标识符方法)。
class Home extends Component {
// Constructor for home
constructor(props) {
super(props);
this.state = {
rewards: [],
cat1Counter: 1,
cat2Counter: 1,
cat3Counter: 1,
cat4Counter: 1,
cat5Counter: 1
};
}
// Fetch rewards once component mounts
componentDidMount() {
this.props.fetchRewards();
}
// Update local state once all rewards are fetched
componentDidUpdate(prevProps) {
if (this.props.rewards !== prevProps.rewards) this.setState({rewards: this.props.rewards});
}
// Creates a unique ID for a reward copy
getUniqueId(prefix) {
let id = '';
if (prefix === 'reward-1') {
id = `${prefix} copy-${this.state.cat1Counter++}`
} else if (prefix === 'reward-2') {
id = `${prefix} copy-${this.state.cat2Counter++}`
} else if (prefix === 'reward-3') {
id = `${prefix} copy-${this.state.cat3Counter++}`
} else if (prefix === 'reward-4') {
id = `${prefix} copy-${this.state.cat4Counter++}`
} else if (prefix === 'reward-5') {
id = `${prefix} copy-${this.state.cat5Counter++}`
}
return id;
}
// Allow for elements to be dropped in other elements
allowDrop(e) {
e.preventDefault();
}
// Removes a node
removeNode(node) {
node.parentNode.removeChild(node);
}
// Drags a reward
drag(e) {
e.dataTransfer.setData('text', e.target.id);
}
// Drops the reward
drop(e) {
e.preventDefault();
const data = e.dataTransfer.getData('text');
const isLeft = 'reward-1' === data || 'reward-2' === data;
const nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = `${this.getUniqueId(data)}`;
if (isLeft) {
e.target.appendChild(nodeCopy);
} else {
if (e.target.id !== 'P') {
this.removeNode(document.getElementById(data));
e.target.appendChild(nodeCopy);
}
}
e.stopPropagation();
return false;
}
render () {
return (
<div className="home-container">
<div className="rewards-container">
<h2>Rewards</h2>
<ul>
{this.state.rewards.map(reward => <li key={reward._id} draggable onDragStart={e => this.drag(e)}>{reward.name}</li>)}
</ul>
</div>
<div className="categories-container">
<h2>Categories</h2>
<div className="list-wrapper">
<ul id="category-1" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C1</p></ul>
<ul id="category-2" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C2</p></ul>
<ul id="category-3" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C3</p></ul>
<ul id="category-4" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C4</p></ul>
<ul id="category-5" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C5</p></ul>
</div>
</div>
</div>
);
}
};更新
根据下面的答案,我已经将onDrag更改为onDragStart,现在它可以在将对象从奖励列表中拖到类别中时工作;但是,当我尝试在类别之间拖动克隆对象时,bug仍然会弹出。
发布于 2020-05-19 17:06:29
您必须设置数据onDragStart。每次拖动时都会调用onDrag,并且可能不是设置的正确位置。您可以将onDrag更改为onDragStart
https://stackoverflow.com/questions/61896681
复制相似问题