javascript - 我今天遇到了 window.addEventListener 和 React Native 的问题

标签 javascript reactjs react-native

我试图使用我在这里找到的这个函数来实现我的 react 应用程序的动态重新渲染: 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 中不存在窗口的事件监听器,因此我们必须模拟它。我不明白那是什么意思。我仍然不知道为什么我找到的解决方案有效。我想了解一下。有人可以启发我吗?

最佳答案

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

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

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

在设备上的 React Native 上,在我的测试中,您的解决方案不会产生错误,但它实际上也不会为您提供尺寸。幸运的是,您可以使用 Dimensions 来获取屏幕尺寸,Expo 也在网络版本中公开了该尺寸。因此,这将在 native 应用程序和 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 中看到。

关于javascript - 我今天遇到了 window.addEventListener 和 React Native 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66145171/

相关文章:

javascript - 音高检测 - Node.js

ruby-on-rails - 本地运行 React/Rails 应用程序

javascript - 使用 Requirejs 通过 Highcharts 加载 'theme' 和 'exporting' 模块

javascript - jQuery.bind() 和 jQuery.on() 有什么区别?

javascript - angularjs $watch 在指令中不起作用

react-native - react native : Vertically and Horizontally align image and text in same row

javascript - 使用从 Alphavantage 返回的 axios 对象更新 ReactJS 状态

javascript - 类型 'Firebase' 不可分配给类型 'null' 。 TS2322

javascript - 在另一个元素上 react setState

reactjs - 在 React Native 中呈现虚拟数据时,Map 函数不起作用