延迟react onMouseOver 事件

IT技术 javascript reactjs events mouseevent dom-events
2021-05-08 07:29:03

我有一个元素列表,当悬停其中一个时,我想改变我的状态。

<ListElement onMouseOver={() => this.setState({data})}>Data</ListElement>

不幸的是,如果我将鼠标移到列表上,我的状态会快速连续更改几次。我想延迟状态更改,以便它在被解雇前等待半秒。有没有办法这样做?

4个回答

这里有一个方法,你可以使用的组合延迟500毫秒通过您的活动onMouseEnteronMouseLeavesetTimeout

请记住,数据的状态更新可以由父组件管理并作为props传入。

import React, { useState } from 'react'

const ListElement = () => {
    const [data, setData] = useState(null)
    const [delayHandler, setDelayHandler] = useState(null)

    const handleMouseEnter = event => {
        setDelayHandler(setTimeout(() => {
            const yourData = // whatever your data is

            setData(yourData)
        }, 500))
    }

    const handleMouseLeave = () => {
        clearTimeout(delayHandler)
    }

    return (
        <div
            onMouseEnter={handleMouseEnter}
            onMouseLeave={handleMouseLeave}
        >
            I have a delayed event handler
        </div>
    )
}

export default ListElement

您可以将其debounce用作专用包或从lodash等处获取:

用于实现仅应在重复操作完成后发生的行为。

const debounce = require('debounce');

class YourComponent extends Component {
  constructor(props) {
    super(props);

    this.debouncedMouseOver = debounce(handleMouseOver, 200);
  }

  handleMouseOver = data => this.setState({ data });

  render() {
    const data = [];
    return <ListElement onMouseOver={() => this.debouncedMouseOver(data)}>Data</ListElement>;
  }
}

您可以创建一个onMouseOver在匹配特殊要求时触发事件的方法

在进一步的示例中,它在 之后触发500 ms

/**
 * Hold the descriptor to the setTimeout
 */
protected timeoutOnMouseOver = false;

/**
 * Method which is going to trigger the onMouseOver only once in Xms
 */
protected mouseOverTreatment(data) {
   // If they were already a programmed setTimeout
   // stop it, and run a new one
   if (this.timeoutOnMouseOver) {
     clearTimeout(this.timeoutOnMouseOver);
   }

   this.timeoutOnMouseOver = setTimeout(() => {
      this.setState(data);

      this.timeoutOnMouseOver = false;
   }, 500);
}

我可能有点晚了,但我想使用 Lodash 添加到上面的一些答案中debounce对方法进行去抖动时,该debounce函数可让您根据某个事件取消对方法的调用。请参阅功能组件的示例:

const [isHovered, setIsHovered] = React.useState(false)

const debouncedHandleMouseEnter = debounce(() => setIsHovered(true), 500)

const handlOnMouseLeave = () => {
  setIsHovered(false)
  debouncedHandleMouseEnter.cancel()
}

return (
  <div
    onMouseEnter={debouncedHandleMouseEnter}
    onMouseLeave={handlOnMouseLeave}
  >
   ... do something with isHovered state...
  </div>
)

此示例允许您仅在用户在您的元素中悬停 500 毫秒后调用您的函数,如果鼠标离开该元素,则调用将被取消。