我试图在鼠标悬停在另一个div元素上时显示div。我已经通过onMouseEnter和onMouseLeave做到了这一点。
这里的问题是,如果您快速从一个div移到另一个div(这是一个包含产品数据的div数组),则index [0]的值将变为true。
它的工作方式是当鼠标进入其中一个数组时,我将其初始化为false,该数组变为true,并显示所需的div。离开后,将其设置回false。
this.state = {
isProductsHovering: new Array(this.props.currentProducts.length).fill(false)
};
handleMouseHover = (idx) => {
this.setState({
isProductsHovering: update(this.state.isProductsHovering, {
[idx]: { $set: !this.state.isProductsHovering[idx] }
})
})
}
render() {
return this.props.currentProducts.map((product, idx) => {
return <Fragment key={idx}>
<div className="product-grid-view col-6 col-md-4" >
<div
className=" product-holder"
onMouseEnter={this.handleMouseHover.bind(this, idx)}
onMouseLeave={this.handleMouseHover.bind(this, idx)}>
<div className="image-container" align="center">
<img src={"/img/product-3.jpg"} alt="" />
{
this.state.isProductsHovering[idx] &&
<div className="product-buttons">
<Link to={`products/${product.id}`} className="btn-detail" text="View Details" />
<Link to='#' className="btn-cart" icons={["icon-cart", "icon-plus"]} />
</div>
}
</div>
<div className="details-holder">
<span className="part-text">{product.desc}</span><br />
<span className="manufacturer-text">{product.manufacturer.name}</span>
<div className="product-review_slide">
<Stars values={product.averageRating} {...starsRating} />
<span className="product-review">{getLength(product.reviews)} review</span>
</div>
<span className="product-price">{product.salesPrice.toFixed(2)}</span>
<span className="product-currency">SR</span>
</div>
</div>
</div>
</Fragment>
})
}
更新
我做了一个stackblitz项目,以重现与建议相同的问题:
https://stackblitz.com/edit/react-mouse-hover。
对于每个想要明白我的意思的人。我已附上问题的照片。如果将鼠标移到两个div上(尽可能快地上下移动),则会发生这种情况:
答案 0 :(得分:2)
对于这种情况,我不会依靠数组和索引来使其工作。您会使handleMouseHover
函数和isHovering的检查更加复杂。
处理这种情况的一种“更多反应”方法就是简单地使每个产品本身成为一个组件。并且此Product
组件将具有自己的isHovered
和handleOnHover
方法状态,这样您就可以创建更简洁和可靠的代码,而不必完全依赖数组index
:
App.js 可以很简单:
class App extends Component {
render() {
return (
<div>
{
data.map(product =>
<Product product={product} />
)
}
</div>
)
}
}
新的 Product.js :
import React from 'react'
import ReactHoverObserver from 'react-hover-observer';
export default class Product extends React.Component {
render() {
const { product } = this.props
return (
<ReactHoverObserver className="product-grid-view col-6 col-md-4">
{
({isHovering}) => (
<div className=" product-holder">
<div className="image-container" align="center">
<img src={"/img/product-3.jpg"} alt="" />
{
isHovering &&
<div className="product-buttons">
<button className="btn-detail">View Details</button>
</div>
}
</div>
<div className="details-holder">
<span className="part-text">{product.desc}</span><br />
<span className="manufacturer-text">{product.manufacturer.name}</span>
<div className="product-review_slide">
<span className="product-review">0 review</span>
</div>
<span className="product-price">{product.salesPrice.toFixed(2)}</span>
<span className="product-currency">Currency</span>
</div>
</div>
)
}
</ReactHoverObserver>
)
}
}
我已将管理人员放在Stackblitz中:https://stackblitz.com/edit/react-mouse-hover-2cad4n
答案 1 :(得分:1)
Liren的答案是一个很好的建议,将有助于简化代码。我还注意到的一件事是,HoverObserver有时不会“听到”事件,并且由于悬停进入和悬停退出事件正在侦听同一事件,因此按钮的显示状态将变为相反的状态(即,它将在鼠标没有悬停时显示;在鼠标悬停在观察者上方时隐藏)。
我建议您摆脱ReactHoverObserver HOC,而只是监听onMouseOver进行悬浮输入,以及onMouseLeave进行悬浮退出。这样,即使div没有注册悬停进入或退出,它也将很容易重置,因为onMouseOver会将显示状态切换为true,而onMouseLeave会将按钮的显示状态可靠地设置为false。
在此处查看文档中的这些事件: https://reactjs.org/docs/events.html#mouse-events
答案 2 :(得分:0)
(从数组或组件中)触发它的方式是语义,真正的问题是这些事件并不总是触发。
我遇到了同样的问题,显然反应的事件不是那么可靠。 就我而言,我可能生活在一个工具提示没有关闭的情况下,但是没有生活在两个工具提示都打开的情况下。为了解决我的问题,我恢复了旧的dom操作-每次出现工具提示时,都会使其他所有工具提示不可见。
它看起来像这样:
showTooltip() {
// Clear old tooltips, EventTooltip is the name of my tooltip class.
Array.from(document.getElementsByClassName('EventTooltip'))
.forEach(tooltip=>tooltip.style = 'display:none;')
this.setState({showTooltip: true})
}
hideTooltip() {
this.setState({showTooltip: false})
}