首页 文章

React Native:使用redux saga eventChannel从组件中外部化事件侦听器

提问于
浏览
2

Redux saga eventChannel 是一个非常优雅的解决方案,可以连接到组件代码外部的外部事件,使它们更清晰,更简洁 . 用例可能是对全局App状态更改做出反应,例如前台应用程序,后台应用程序,非活动状态......

当谈到React Native时,我担心取消订阅过程 . 在内部组件中, componentWillUnmount 是执行取消订阅的地方,因此我们有一些UI挂钩可以保证我们删除侦听器的成功 .

例如,当我应用以下代码时,为了跟踪应用程序状态更改(活动,非活动或后台),我是否可以暴露于内存泄漏?

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,其中有几个反应根视图(每个屏幕一个),这就是为什么HOC不适合这种情况,因为我必须用HOC包装每个父屏幕,如果我有3个屏幕被推入堆栈,在app恢复逻辑将被执行3次 .

1 回答

  • 0

    所以显然它取决于本机模块的实现 .

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

    但是,如果在本机端处理新的侦听器,那么如果JS上下文被杀死则会出现问题,因为内存将被泄露 .

    在JS方面保留订阅的两个模块的示例是 AppStateBackHandler . 两者都在本机端保留一个全局侦听器,在JS端保留多个订阅者,因此两者都可以安全地与redux-saga eventChannel 一起使用 .

    您可以在此处查看 AppState 的源代码作为示例:https://github.com/facebook/react-native/blob/master/Libraries/AppState/AppState.js

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

相关问题