React hook useState 更新组件的所有实例
React hook useState updating all instances of component
我正在尝试使用 useState 创建一张卡片,其背景图像随着鼠标在其上的移动而变化。
代码工作正常,但是如果我在卡片上移动时创建卡片组件的多个实例,它会导致卡片的所有实例的状态更新。如何防止我的代码执行此操作?
组件的实例化:
<div className="aboutCardContainer">
{Object.entries(members).map(([key,value])=>{
return(<AboutCard key={key} id={key} {...value}/>)
})}
</div>
组件代码:
import React, { useState } from "react";
import { Link } from "react-router-dom";
import $ from 'jquery';
const AboutCard = ({id, name, role, description, link, image, colored_image}) => {
const [backImg, setBackImg] = useState(0);
var active = 0;
var currentProfile = 0;
var unitPhoto= 0;
$(document).on('mousemove', '.profileImage', function(event){
var id = $(this).parent().parent().attr('id');
currentProfile=id;
if(id !== currentProfile){
return;
}
unitPhoto = 100/(image.length-1);
var offset = $(this).offset();
let x = event.pageX- offset.left;
let w =$( this ).width();
x = (x*100)/w;
let index = Math.floor(x/unitPhoto);
if(index === 0){
setBackImg(colored_image);
return;
}
if(index >= image.length){
index = image.length-1;
}
if(index <0){
return;
}
if(index !== active || index != colored_image){
setBackImg(index);
active=index;
}
});
$(document).on('touchmove', '.profileImage', function(event){
var id = $(this).parent().parent().attr('id');
if(id !== currentProfile){
currentProfile=id;
unitPhoto = 100/(image.length-1);
}
var offset = $(this).offset();
let x = event.touches[0].pageX - offset.left;
let w =$( this ).width();
x = (x*100)/w;
let index = Math.floor(x/unitPhoto);
if(index === 0){
setBackImg(colored_image);
}
if(index >= image.length){
index = image.length-1;
}
if(index <0){
return;
}
if(index !== active || index != colored_image){
setBackImg(index);
active=index;
}
});
return (
<div className="aboutDiv" id={id}>
<Link to={`${link}`}>
<div id={'image-'+id} style={{
background: `url(${image[backImg]})`,
}} className="profileImage">
</div>
</Link>
<h3 className="profileName">{name}</h3>
<p className="profileRole">{role}</p>
</div>
);
};
export default AboutCard;
这是因为您的 jQuery 事件侦听器正在侦听文档范围内的通知。也就是说,所有 AboutCard 的 mousemove 侦听器将 运行 每次在具有 class profileImage 的元素上发生 mousemove 事件(这是您的组件的每个实例)时。
我会避免像这样混合使用 jQuery 和 React - 它们各自以不同的方式操纵 dom。在您的组件中创建一个本地引用(useRef)并以反应方式附加一个 eventListener,它只监听本地引用上的事件。
我正在尝试使用 useState 创建一张卡片,其背景图像随着鼠标在其上的移动而变化。 代码工作正常,但是如果我在卡片上移动时创建卡片组件的多个实例,它会导致卡片的所有实例的状态更新。如何防止我的代码执行此操作?
组件的实例化:
<div className="aboutCardContainer">
{Object.entries(members).map(([key,value])=>{
return(<AboutCard key={key} id={key} {...value}/>)
})}
</div>
组件代码:
import React, { useState } from "react";
import { Link } from "react-router-dom";
import $ from 'jquery';
const AboutCard = ({id, name, role, description, link, image, colored_image}) => {
const [backImg, setBackImg] = useState(0);
var active = 0;
var currentProfile = 0;
var unitPhoto= 0;
$(document).on('mousemove', '.profileImage', function(event){
var id = $(this).parent().parent().attr('id');
currentProfile=id;
if(id !== currentProfile){
return;
}
unitPhoto = 100/(image.length-1);
var offset = $(this).offset();
let x = event.pageX- offset.left;
let w =$( this ).width();
x = (x*100)/w;
let index = Math.floor(x/unitPhoto);
if(index === 0){
setBackImg(colored_image);
return;
}
if(index >= image.length){
index = image.length-1;
}
if(index <0){
return;
}
if(index !== active || index != colored_image){
setBackImg(index);
active=index;
}
});
$(document).on('touchmove', '.profileImage', function(event){
var id = $(this).parent().parent().attr('id');
if(id !== currentProfile){
currentProfile=id;
unitPhoto = 100/(image.length-1);
}
var offset = $(this).offset();
let x = event.touches[0].pageX - offset.left;
let w =$( this ).width();
x = (x*100)/w;
let index = Math.floor(x/unitPhoto);
if(index === 0){
setBackImg(colored_image);
}
if(index >= image.length){
index = image.length-1;
}
if(index <0){
return;
}
if(index !== active || index != colored_image){
setBackImg(index);
active=index;
}
});
return (
<div className="aboutDiv" id={id}>
<Link to={`${link}`}>
<div id={'image-'+id} style={{
background: `url(${image[backImg]})`,
}} className="profileImage">
</div>
</Link>
<h3 className="profileName">{name}</h3>
<p className="profileRole">{role}</p>
</div>
);
};
export default AboutCard;
这是因为您的 jQuery 事件侦听器正在侦听文档范围内的通知。也就是说,所有 AboutCard 的 mousemove 侦听器将 运行 每次在具有 class profileImage 的元素上发生 mousemove 事件(这是您的组件的每个实例)时。
我会避免像这样混合使用 jQuery 和 React - 它们各自以不同的方式操纵 dom。在您的组件中创建一个本地引用(useRef)并以反应方式附加一个 eventListener,它只监听本地引用上的事件。