Javascript 在ReactJs中通过拖放交换两个图像
使用ReactJs,当用户拖动图像然后放到另一个图像上时,它们应该交换Javascript 在ReactJs中通过拖放交换两个图像,javascript,reactjs,Javascript,Reactjs,使用ReactJs,当用户拖动图像然后放到另一个图像上时,它们应该交换 class App extends Component { constructor(props) { super(props); this.state = { arr: [ { name: 'src1', src: 'https://source.un
class App extends Component {
constructor(props) {
super(props);
this.state = {
arr: [
{
name: 'src1',
src: 'https://source.unsplash.com/user/erondu/200x300'
},
{
name: 'src2',
src: 'https://picsum.photos/200/300'
},
{
name: 'src3',
src: 'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back01.jpg'
},
{
name: 'src4',
src: 'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back05.jpg'
}
],
dragImgName: null,
dragImgSrc: null,
dropImgName: null,
dropImgSrc: null,
dragImgObj: null
}
}
dragWord(item) {
//got the object of dragged image array
this.setState({ dragImgName: item.name });
this.setState({ dragImgSrc: item.src });
}
dropWord(event, item) {
//Item got the object of that image on which drag going to happen.
// console.log(item.src);
event.preventDefault();
var tempDropImg = item.src;
var tempDragImg = this.state.dragImgSrc;
this.setState({ dropImgSrc: item.src })
this.setState({
arr: this.state.arr.map(el => {
console.log(el, this.state.dragImgSrc);
// return (el.src === tempDropImg ? { ...el, src: tempDragImg } : el)
return (el.src === tempDropImg ? Object.assign({}, el, { src: tempDragImg }) : el)
})
});
this.setState({
// arr: this.state.arr.map(el => (el.src === tempDragImg ? { ...el, src: tempDropImg } : el))
arr: this.state.arr.map(el => (el.src === tempDragImg ? Object.assign({}, el, { src: tempDropImg }) : el))
});
}
render() {
return (<>
<div>
<p>Drag and drop the pictures in order to show.</p>
</div>
{
this.state.arr.map(item => {
return (<div key={item.name} onDragOver={(event) => event.preventDefault()}
name={`${item.name}`} onDrop={(event) => this.dropWord(event, item)} >
<div className="mover boxA" draggable="true" onDragStart={() => { this.dragWord(item) }} >
<img src={item.src} alt={item.name} style={{ height: 140, width: 140 }} />
</div>
</div>)
})
}
</>);
}
}export default App;
类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
arr:[
{
名称:“src1”,
src:'https://source.unsplash.com/user/erondu/200x300'
},
{
名称:'src2',
src:'https://picsum.photos/200/300'
},
{
名称:“src3”,
src:'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back01.jpg'
},
{
名称:'src4',
src:'http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back05.jpg'
}
],
德拉金纳姆:空,
dragImgSrc:null,
dropImgName:null,
dropImgSrc:null,
dragImgObj:null
}
}
德拉格沃德(项目){
//获取拖动图像数组的对象
this.setState({dragimname:item.name});
this.setState({dragImgSrc:item.src});
}
dropWord(事件、项目){
//Item获得了将要进行拖动的图像的对象。
//console.log(item.src);
event.preventDefault();
var tempDropImg=item.src;
var tempDragImg=this.state.dragImgSrc;
this.setState({dropImgSrc:item.src})
这是我的国家({
arr:this.state.arr.map(el=>{
log(el,this.state.dragImgSrc);
//返回(el.src===tempDropImg?{…el,src:tempDragImg}:el)
return(el.src===tempDropImg?Object.assign({},el,{src:tempDragImg}):el)
})
});
这是我的国家({
//arr:this.state.arr.map(el=>(el.src===tempDragImg?{…el,src:tempDropImg}:el))
arr:this.state.arr.map(el=>(el.src===tempDragImg?Object.assign({},el,{src:tempDropImg}):el))
});
}
render(){
返回(
拖放图片以显示
{
this.state.arr.map(项=>{
返回(event.preventDefault()}
name={${item.name}}}onDrop={(事件)=>this.dropWord(事件,项目)}>
{this.dragWord(项目)}>
)
})
}
);
}
}导出默认应用程序;
我尝试了所有可能的方法,搜索了很多,但我在React Native中得到了这个解决方案。我也使用了更新方法,仍然没有发生任何事情。查看我的更新代码。
注意-注释更改代码中第55行的设置状态。代码的问题是,您在
dropWord
方法上设置了三次状态,第三次调用设置状态
,您覆盖了之前为更改arr
变量所做的调用
您不需要在dropWord
方法上调用setState
三次,我建议您使用交换的图像创建列表,然后设置状态。设置状态将呈现组件,因此应尽量减少设置状态调用
将您的dropWord
方法更改为以下代码,它应该可以工作:
dropWord(event, item) {
event.preventDefault();
let tempDropImg = item.src;
let tempDragImg = this.state.dragImgSrc;
this.setState({
dropImgSrc: item.src,
arr: this.state.arr.map(el => {
if (el.src === tempDropImg) return { ...el, src: tempDragImg };
if (el.src === tempDragImg) return { ...el, src: tempDropImg };
return el;
})
});
}
同样的逻辑也适用于dragWord
函数。您不需要调用setState
两次。最好改为:
dragWord(item) {
this.setState({ dragImgName: item.name, dragImgSrc: item.src });
}
代码的问题是,您在
dropWord
方法上设置了三次状态,第三次调用setState
,您覆盖了之前所做的调用,以更改arr
变量
您不需要在dropWord
方法上调用setState
三次,我建议您使用交换的图像创建列表,然后设置状态。设置状态将呈现组件,因此应尽量减少设置状态调用
将您的dropWord
方法更改为以下代码,它应该可以工作:
dropWord(event, item) {
event.preventDefault();
let tempDropImg = item.src;
let tempDragImg = this.state.dragImgSrc;
this.setState({
dropImgSrc: item.src,
arr: this.state.arr.map(el => {
if (el.src === tempDropImg) return { ...el, src: tempDragImg };
if (el.src === tempDragImg) return { ...el, src: tempDropImg };
return el;
})
});
}
同样的逻辑也适用于dragWord
函数。您不需要调用setState
两次。最好改为:
dragWord(item) {
this.setState({ dragImgName: item.name, dragImgSrc: item.src });
}
谢谢!它解决了我的问题。是的,我知道由于多次设置,它覆盖了前一个设置。但是我没有办法摆脱它。你用if-else替换了那段代码,但是我想使用类似
this.setState({arr:this.state.arr.map(el=>{console.log(el,this.state.dragImgSrc);//return(el.src==tempDropImg?{…el,src:tempDragImg}:el)return(el.src===tempDropImg?Object.assign({},el,{src:tempDragImg}):el)})
表示spread opr.或Obj.有什么想法吗?@Diogo我已经编辑了答案,请检查这是否是您想要的,我看不到没有条件的方法。谢谢您的答案,它已经用您的第一个答案解决了我的问题。@Diogothis.setState({dropImgSrc:item.src,arr:this.state.arr.map(el=>{el.src===tempDropImg?{…el,src:tempDragImg}:el.src===tempDragImg?{…el,src:tempDropImg}:el;})
通过这种方式,您可以从编辑的答案中替换if-else条件。@RajatSharma感谢您的反馈,我已经编辑了答案以插入您的建议答案。很高兴这有帮助,祝您的项目好运Hey@Diogo我在测试的基础上得到了一个新项目,我从您的解决方案中解决了这个问题。谢谢!祝您有一天愉快!:顺便说一句,你有多少经验?非常感谢!它解决了我的问题。是的,我知道是由于多重原因