【问题标题】:I had an issue today with window.addEventListener and React Native我今天遇到了 window.addEventListener 和 React Native 的问题
【发布时间】:2021-05-14 15:06:20
【问题描述】:

我试图使用我在这里找到的这个函数来实现我的反应应用程序的动态重新渲染: https://stackoverflow.com/a/19014495/7838374

function useWindowSize() {
  const [size, setSize] = useState([0, 0]);
  useLayoutEffect(
    () => {
      function updateSize() {
        setSize([window.innerWidth, window.innerHeight]);
      }
      window.addEventListener("resize", updateSize);
      updateSize();
      return () => window.removeEventListener("resize", updateSize);
    },[]);
  return size;
}

function ShowWindowDimensions(props) {
  const [width, height] = useWindowSize();
  return (
    <span>
      Window size: {width} x {height}
    </span>
  );
}

链接到我的应用程序: https://github.com/Intetra/aubreyw

当我在桌面上的浏览器中显示我的应用程序时,我能够让一切正常运行。我正在使用 expo 来运行应用程序。当我尝试在我的 android 手机上运行该应用程序时,问题就来了。我在启动时遇到错误。

组件异常:window.addEventListener 不是函数

我能够使用我在这里找到的解决方案让它工作: https://stackoverflow.com/a/61470685/7838374

那个解决方案说在 react native 中不存在 window 的事件监听器,所以我们必须模拟它。我不明白那是什么意思。我仍然不知道为什么我找到的解决方案有效。我想了解。有人可以启发我吗?

【问题讨论】:

  • 您想从 react-native 导入维度并使用 Dimensions.addEventListener 来完成。但是你也需要去抖动这个东西。它有点复杂,但你可以谷歌它。 Debounce 意味着您在调整窗口大小后稍等片刻,然后再计算调整大小,否则它将尝试每秒调整 60 次以上,这会影响性能

标签: javascript reactjs react-native


【解决方案1】:

浏览器环境在某些方面与 React Native 环境不同,尽管两者都使用 Javascript。这意味着虽然语言相同,但某些基本功能可能不同,这意味着它们的行为可能不同,或者存在于一个地方而不是另一个地方。

window.addEventListener 是我们可以期望在浏览器世界中存在但在 React Native 中未实现的示例。当然,Expo 会稍微复杂一些,它允许通过填充某些功能在 Web 上运行 React Native 代码,试图弥合两个世界之间的一些差异。

由于 Javascript 的动态特性,即使 iOS/Android 上的 React Native 不提供 window.addEventListener,我们也可以通过自己定义将其添加到我们的环境中。这就是您找到的解决方案 (window.addEventListener = x =&gt; x) 所做的 - 它只是添加了一个实际上不执行任何操作的函数(它以 x 作为参数并返回 x 作为结果)。这有时被称为模拟——你会经常在测试世界中看到它。

在设备上的 React Native 上,在我的测试中,您的解决方案不会产生错误,但它实际上也不会为您提供尺寸。幸运的是,您可以使用Dimensions 来获取屏幕尺寸,Expo 也在网页版中公开了该尺寸。因此,这看起来会在本机应用程序和 Expo Web 版本上返回正确的大小:


function useWindowSize() {
  const [size, setSize] = React.useState([0, 0]);
  React.useLayoutEffect(
    () => {
      console.log("Layout effect")
      function updateSize() {
        setSize([Dimensions.get('window').width, Dimensions.get('window').height])
      }
      window.addEventListener("resize", updateSize);
      updateSize();
      return () => window.removeEventListener("resize", updateSize);
    },[]);
  return size;
}

注意,您应该做一些测试,看看在旋转、调整大小等时会发生什么——我只确保基本功能正常工作。

这是一个带有上下文代码的小吃:https://snack.expo.io/Mofut1jHa

另请注意,window.removeEventListener 也必须被模拟,您可以在 Snack 中看到。

【讨论】:

    猜你喜欢
    • 2021-01-15
    • 2020-11-08
    • 1970-01-01
    • 2019-03-27
    • 2020-01-04
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 2020-11-07
    相关资源
    最近更新 更多