【问题标题】:Redux saga: yield put not working inside nested callbackRedux 传奇:yield put 在嵌套回调中不起作用
【发布时间】:2018-07-08 12:04:04
【问题描述】:
const { payload: {loginType, email, password, notification, self} } = action;

  console.log("--TRY--");
  Firebase.login(loginType, { email, password })
    .catch(function(result) {
      const message =
        result && result.message ? result.message : 'Sorry Some error occurs';
      notification('error', message);
      self.setState({
        confirmLoading: false
      });
      isError = true;
    })
    .then(function(result) {
      if (isError) {
        return;
      }
      if (!result || result.message) {
        const message =
          result && result.message
            ? result.message
            : 'Sorry Some error occurs';
        notification('error', message);
        self.setState({
          confirmLoading: false
        });
      } else {
        self.setState({
          visible: false,
          confirmLoading: false
        });
        console.log("--RIGHT BEFORE I CHECK AUTH STATE--");

        //the following does NOT fire
        firebaseAuth().onAuthStateChanged(function*(user) {
              console.log("THE GENERATOR RUNS");
              if (user) {
                  console.log(user);
                  yield put({
                      type: actions.LOGIN_SUCCESS,
                      token: 'secret token',
                      profile: 'Profile'
                  });
                  yield put(push('/dashboard'));
              }
              else {
                  yield put({ type: actions.LOGIN_ERROR });
              }
          });
      }
  }); });

嗨。我目前是第一次使用 redux saga。我一直试图在 firebaseAuth().onAuthStateChanged 监听器的回调中触发 yield。 yield 关键字在不是 ES6 生成器的函数中不起作用,所以我在回调中添加了一个星号,但现在它根本不会执行。非常感谢您对此事的任何建议。

【问题讨论】:

    标签: ecmascript-6 redux firebase-authentication generator redux-saga


    【解决方案1】:

    正如您所注意到的,redux-saga 效果只能在生成器函数中使用,并且不能将生成器函数用作常规函数:调用生成器函数只会返回一个特殊对象。

    解决这个问题的正确方法是使用eventChannel:它可以让您将您的传奇连接到 redux 生态系统外部的事件源。

    首先使用提供的工厂函数创建您的eventChannel:它为您提供一个可用于发出事件的emit 函数;然后使用take 效果使用这些事件。

    import { eventChannel } from 'redux-saga';
    import { cancelled, take } from 'redux-saga/effects';
    
    // first create your eventChannel
    const authEventsChannel = eventChannel( emit => {
      const unsubscribe = firebaseAuth().onAuthStateChanged( user => {
        emit({ user });
      });
      // return a function that can be used to unregister listeners when the saga is cancelled
      return unsubscribe;
    });
    
    // then monitor those events in your saga
    try {
      while (true) {
        const { user } = yield take (authEventsChannel);
        // handle auth state
      }
    } finally {
      // unregister listener if the saga was cancelled
      if (yield cancelled()) authEventsChannel.close();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-14
      • 2017-08-19
      • 1970-01-01
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      相关资源
      最近更新 更多