Мышь зависает в React - PullRequest
       22

Мышь зависает в React

0 голосов
/ 31 декабря 2018

Я пытаюсь отобразить div, когда мышь находится над другим элементом div.Мне удалось сделать это через onMouseEnter и onMouseLeave.

Проблема здесь в том, что если вы быстро переходите от одного div к другому (это массив div, который содержит данные о продукте), значение индекса[0] становится истинным.

То, как это работает, заключается в том, что у меня есть массив, инициализированный как ложный, когда мышь входит в один из них, он становится истинным и показывает нужный мне div.Как только он уходит, он устанавливает его обратно в ложь.

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.

Для всех, кто хочет понять, что я имею в виду.Я приложил фотографию вопроса.Если вы подведете указатель мыши к двум элементам (как можно быстрее вверх и вниз), вот что произойдет:

перерыв мыши при наведении

Ответы [ 3 ]

0 голосов
/ 31 декабря 2018

В такой ситуации я бы не использовал массив и индекс, чтобы он работал.Кроме того, вы усложняете свои 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>
    )
  }
}

Я поставил микрофилизациюв Штакблице: https://stackblitz.com/edit/react-mouse-hover-2cad4n

0 голосов
/ 31 декабря 2018

То, как вы запускаете его (из массива или из компонента), является семантикой, реальная проблема заключается в том, что эти события не всегда запускаются.

У меня была та же проблема, по-видимому, события реакциине так надежно.В моем случае я мог бы жить в ситуации, когда подсказка не закрывается, но не в ситуации, когда открыты 2 подсказки.Чтобы решить мою проблему, я вернулся к старой доброй манипуляции с домом - каждый раз, когда появлялась подсказка, она делала все остальные невидимыми.

Это выглядело примерно так:

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})
}
0 голосов
/ 31 декабря 2018

Ответ Лирен - хороший совет, который поможет упростить код.Я также заметил, что иногда HoverObserver не «слышит» событие, и, поскольку события при наведении и выходе при наведении слушают одно и то же событие, то состояние отображения кнопки будет изменено на обратное (т.е.показать, когда мышь НЕ зависла, и скрыть, когда мышь находится над наблюдателем).

Я бы порекомендовал избавиться от HOC ReactHoverObserver и вместо этого просто слушать onMouseOver для входа при наведении и onMouseLeave для выхода при наведении.Таким образом, даже если div не регистрирует ввод или выход при наведении, он будет легко сброшен, поскольку onMouseOver переключит состояние отображения на true, а onMouseLeave надежно установит состояние отображения кнопки в false.

См. Здесьдля тех событий в документах: https://reactjs.org/docs/events.html#mouse-events

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...