javascript - react 原生 : using redux saga eventChannel to externalise event listeners from components

标签 javascript react-native redux-saga

Redux 传奇 eventChannel是一个非常优雅的解决方案,可以从组件代码外部连接到外部事件,使它们更简洁。一个用例可能是对全局应用程序状态变化使用react,例如前台应用程序、后台应用程序、非事件......

我担心 React Native 的退订过程。
内部组件,componentWillUnmount是执行取消订阅的地方,因此我们有一些 UI 钩子(Hook)可以保证我们成功删除监听器。

例如,当我应用以下代码来跟踪 App 状态更改(事件、非事件或后台)时,我是否会面临内存泄漏?

type NextAppState = 'active' | 'inactive' | 'background';

function createAppStateChannel() {
  return eventChannel((emit: (nextState: NextAppState) => mixed) => {
    AppState.addEventListener('change', emit);
    return () => {
      AppState.removeEventListener('change', emit);
    };
  });
}

export function* appStateListenerSaga(): Generator<*, *, *> {
  try {
    const appStateChannel = yield call(createAppStateChannel);
    while (true) {
      const nextAppState: NextAppState = yield take(appStateChannel);
      if (nextAppState === 'active') {
        // Do something, like syncing with server
      }
  } finally {
    if (yield cancelled()) {
      appStateChannel.close();
    }
  } 
}

我正在考虑 JS 上下文因某种原因被杀死的情况。

我担心的是 sagas 不会被取消(据我所知),不会执行取消订阅,因此本地监听器将保持注册状态。下次重新打开应用程序时,我们将注册一个重复的事件监听器,依此类推。

任何人都可以指出这是否安全,或者使用 HOC 基本上更好?我也在使用 react-native-navigation 有几个 react Root View (每个屏幕一个),这就是为什么 HOC 不适合这种情况,因为我必须用 HOC 包装每个父屏幕,如果我有 3 个屏幕被推送到堆栈上,在应用程序恢复时,逻辑将被执行 3 次。

最佳答案

所以显然它取决于 native 模块的实现。

如果原生模块只保留一个监听器,并且所有订阅都在 JS 端进行管理,那么这不是问题。

但是,如果在原生端处理新的监听器,如果 JS 上下文被杀死,因为内存会泄漏,这将是一个问题。
AppState 是在 JS 端保持订阅的两个模块的示例。和 BackHandler .两者都在 native 端保留一个全局监听器,在 JS 端保留多个订阅者,因此两者都可以安全地与 redux-saga eventChannel 一起使用.

可以查看AppState的源代码以这里为例:https://github.com/facebook/react-native/blob/master/Libraries/AppState/AppState.js

我还没有偶然发现一个相反的模块。
根据经验,只需浏览 github 源代码上的模块即可了解如何管理订阅。

关于javascript - react 原生 : using redux saga eventChannel to externalise event listeners from components,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48178222/

相关文章:

javascript - 在 Backbone.js 中有条件地执行路由

react-native - 如何在 react 原生平面列表中一次选择一个单选按钮

react-native - redux-saga 上的游戏循环

javascript - 防止滚动从元素冒泡到窗口

javascript - 如何在 Node.js 中将字符串转换为变量名?

android - 为什么我来自 url 的图像没有出现在 TouchableOpacity 中

javascript - 如何在 React Native 中刷新屏幕?

javascript - 如何访问 saga 函数内的操作值

typescript - 预期有 0​​ 个参数的问题,但在 Redux Toolkit 中得到 1

javascript - 在 id div 中找到所有复选框并选中并隐藏其他未选中的