在某些情况下如何删除React钩子?

时间:2019-06-26 16:06:32

标签: reactjs event-listener react-hooks

在转到下一页部分时找不到删除钩子的方法。

我创建了一个“ useMousePosition”钩子,该钩子跟踪鼠标的位置并返回鼠标坐标绞盘,以用于转换某些<div/>的位置。向下滚动页面时,无需转换<div/>,因此我想删除此useMousePosition挂钩。

useMouseHook

function useMousePosition() {
  let [mousePosition, setMousePosition] = useState({
    x: null,
    y: null
  });


function handleMouseMove(e) {
  setMousePosition({
    x: e.pageX,
     y: e.pageY
  });
}

useEffect(() => {
  window.addEventListener("mousemove", handleMouseMove);
    return () => {
      window.removeEventListener("mousemove", handleMouseMove);
    };
  }, []);

  return mousePosition;
}

在此类组件中使用钩子

let { x, y } = useMousePosition();

当用户滚动到下一页部分时,我需要删除一个钩子(带有钩子的组件不会卸载)

2 个答案:

答案 0 :(得分:2)

我理解问题的方式是,您想停止跟踪鼠标的移动。

如果我的理解是正确的,则可以传递一个标志来开始/顶部跟踪鼠标的移动。

此演示显示您可以打开/关闭鼠标跟踪,并且

您可以跟随 Edit so.answer.56777009

demo

您只需传递一个变量,即可在useEffect中进行检查。

function useMousePosition(shouldTrack = true) {
  let [mousePosition, setMousePosition] = useState({
    x: null,
    y: null
  });

  function handleMouseMove(e) {
    setMousePosition({
      x: e.pageX,
      y: e.pageY
    });
  }

  useEffect(() => {
    if (!shouldTrack) return;

    window.addEventListener("mousemove", handleMouseMove);
    return () => {
      window.removeEventListener("mousemove", handleMouseMove);
    };
  }, [shouldTrack]);

  return mousePosition;
}

function App() {
  const [useMouse, setUseMouse] = useState(true);
  let { x, y } = useMousePosition(useMouse);

  useEffect(() => {
    console.log(`x, y`, x, y);
  }, [x, y]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={() => setUseMouse(_ => !_)}>
        Tracking Mouse Movement is {useMouse ? "On" : "Off"}
      </button>
    </div>
  );
}

单击按钮可切换曲目状态。

对于“卸下挂钩”,您不能这样做,因为它已嵌入在功能组件中。 您至少可以使用条件阻止“副作用”。

⚠请注意,useEffect[shouldTrack]的依赖关系。

答案 1 :(得分:0)

您需要在handleMouseMove

中指定条件

在下一个解决方案中,您将停止在粉红色边框之外进行渲染,并删除黑线下方的侦听器。

  

注意:由于不必要的渲染,添加了useCallbackdep array

enter image description here

const isInsideBox = ({ pageX, pageY }) =>
  LEFT <= pageX && pageX <= RIGHT && TOP <= pageY;

function useMousePosition() {
  let [mousePosition, setMousePosition] = useState({
    x: null,
    y: null
  });

  const handleMouseMove = useCallback(
    e => {
      isInsideBox(e) &&                     // Add Condition for Border
        setMousePosition({
          x: e.pageX,
          y: e.pageY
        });

      e.pageY >= BOTTOM &&                  // Add Condition for Black Line
        window.removeEventListener("mousemove", handleMouseMove);
    },
    [setMousePosition]
  );

  useEffect(() => {
    window.addEventListener("mousemove", handleMouseMove);
    return () => {
      window.removeEventListener("mousemove", handleMouseMove);
    };
  }, [handleMouseMove]);

  return mousePosition;
}