使用导航进入新屏幕后如何卸载挂钩

How unmount a hook after going to new screen with navigate

上下文是一个带有 React Navigation 的简单 React Native 应用程序。 有3个屏幕。

第一个简单地显示一个按钮,使用 navigation.navigate("SecondScreen") 转到第二个屏幕。

第二个包含一个钩子(见下面的代码),它添加一个侦听器来侦听鼠标位置。此挂钩在 useEffect 挂钩中添加侦听器,并在 useEffect 清理函数中删除侦听器。我只是在监听函数里加了一个console.log,看看什么时候触发函数

此屏幕还包含一个导航至第三个屏幕的按钮,该屏幕仅显示文本。

如果我从第一个屏幕转到第二个屏幕:钩子中的侦听器开始 运行。好的。 如果我在 header 中使用默认的 React Navigation 后退按钮返回到第一个屏幕。听者停了下来。好的。 如果我再次转到第二个屏幕,则侦听器会再次运行。好的。 但是如果我现在从第二屏转到第三屏,监听器还是运行。不好。

如何在进入第三屏时卸载挂钩,返回第二屏时重新挂载?

请在回答前阅读以下内容:

我知道:

那么有谁知道我如何处理这种情况以避免在第三个屏幕上出现听众 运行?

这是钩子示例的代码,我从 https://github.com/rehooks/window-mouse-position/blob/master/index.js 中获取,但可以使用任何钩子。

"use strict";
let { useState, useEffect } = require("react");

function useWindowMousePosition() {
  let [WindowMousePosition, setWindowMousePosition] = useState({
    x: null,
    y: null
  });

  function handleMouseMove(e) {
    console.log("handleMouseMove");
    setWindowMousePosition({
      x: e.pageX,
      y: e.pageY
    });
  }

  useEffect(() => {
    window.addEventListener("mousemove", handleMouseMove);

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

  return WindowMousePosition;
}

module.exports = useWindowMousePosition;

the react navigation's hook useFocusEffect could be used to resolve this kind of problem. But it can't be used here because it will involve to replace the useEffect in the hook by the useFocusEffect. And I want my hook to be usable in every context, even if react navigation is not installed

因此您的挂钩需要以某种方式了解导航状态。如果不能使用 useFocusEffect,则需要传递有关屏幕是否聚焦的信息(例如使用 enabled 属性)。

function useWindowMousePosition({ enabled = true } = {}) {
  let [WindowMousePosition, setWindowMousePosition] = useState({
    x: null,
    y: null
  });

  useEffect(() => {
    if (!enabled) {
      return;
    }

    function handleMouseMove(e) {
      console.log("handleMouseMove");
      setWindowMousePosition({
        x: e.pageX,
        y: e.pageY
      });
    }

    window.addEventListener("mousemove", handleMouseMove);

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

  return WindowMousePosition;
}

然后根据屏幕焦点传递enabled

const isFocused = useIsFocused();
const windowMousePosition = useWindowMousePosition({ enabled: isFocused });

请注意,与 useFocusEffect 不同,此方法需要在 blurred/focused 时重新呈现屏幕。