将观察者传递给 redux-sagas

Posted

技术标签:

【中文标题】将观察者传递给 redux-sagas【英文标题】:Passing observer into redux-sagas 【发布时间】:2017-01-23 00:30:57 【问题描述】:

我正在尝试从 redux-sagas 框架中利用可观察到的 firebase,但是如果没有 hack,我很难做到这一点。我正在尝试使用 firebase 的“onAuthStateChange”函数,如下所示

firebase.auth().onAuthStateChanged(function(user) 
  if (user) 
    // User is signed in.
   else 
    // No user is signed in.
  
);

基本上观察者在用户登录或退出时执行

在我的 firebase 实用程序文件中,我的方法如下所示:

authChanged: () =>
    return firebaseAuth.onAuthStateChanged(callback);

然后在我的传奇中,目前,我只是在观察者观察到某些东西时尝试登录到控制台:

export function* loginState()
    Firebaseutils.authChanged(function(user)
        if(user)
            console.log('User logged in!')
        else
            console.log('User logged out')
        
    );

由于未定义“回调”而失败。我本质上是在试图让观察者传递给 sagas,但它不起作用。我的解决方法是将完整的 firebase auth 对象传递给我的登录/注销 saga,然后在其中创建观察者。这有效,但似乎是一个黑客。任何帮助将不胜感激。

【问题讨论】:

不应该authChangedcallback 作为参数? callback 应该来自哪里? 【参考方案1】:

我认为您实际上并未将observer 集成到您的sn-p 中的saga 中。它适用于 console.log b/c 这是一个同步函数,但你不能从该回调中获得任何东西 yield,因为它的上下文与 generator 的上下文是分开的。这会剥夺你很多sagas 实用程序,如果它在@ all 上工作的话。

我必须在我的项目中完成这项工作,而我能做的最好的事情是受到 this project 和 this starter-kit 中的架构的启发。

基本上就是几步。

    将您的观察者包装在接受dispatch 并返回promise 的函数中。

    export function initAuth(dispatch) 
     return new Promise((resolve, reject) => 
    
    myFirebaseAuthObj.onAuthStateChanged(
      authUser => 
        if (authUser) 
          dispatch(signInFulfilled(authUser))
         else if (authUser === null) 
          dispatch(signOutFulfilled())
        
        resolve()
      ,
    
      error => reject(error)
    )
    )
    
    

    将您的***容器包装在一个函数中

    const initialState = window.___INITIAL_STATE__
    const store = createStore(initialState)
    let render = () => 
      const routes = require('./routes/index').default(store)
    
      ReactDOM.render(
        <AppContainer store=store routes=routes />,
        MOUNT_NODE
      )
    
    

    render() 包裹在initAuth 中:

    initAuth(store.dispatch)
      .then(() => render())
      .catch(error => console.error(error)) 
    

    将您的sagas 用于其他任何事情。例如,您可以像这样从sagas 进行路线更改:

    function* signIn(authProvider) 
      try 
        const authData = yield call([firebaseAuth, firebaseAuth.signInWithPopup], authProvider)
        yield take(SIGN_IN_FULFILLED)
        browserHistory.push('/dash')
      
      catch (error) 
        yield put(signInFailed(error))
      
    
    

【讨论】:

【参考方案2】:

您似乎打算将callback 作为authChanged 的参数,但authChanged 目前没有参数。以下是您可能打算做的事情:

authChanged: (callback) => 
    return firebaseAuth.onAuthStateChanged(callback);

我不确定我理解你所说的 curry 观察者的意思,但你也可以做这样的事情来 curry firebase 方法作为你的方法:


    authChanged: ::firebaseAuth.onAuthStateChanged,

【讨论】:

以上是关于将观察者传递给 redux-sagas的主要内容,如果未能解决你的问题,请参考以下文章

将观察对象的投影值的属性传递给@Binding

如何将可观察值传递给@Input() Angular 4

将 KnockoutJS 可观察数组传递给 HTTP Post 控制器方法的 AJax 调用失败

如何将变量传递给 heml.tf 中的 yaml 文件?

SwiftUI 将@Published viewmodel 对象值传递给@Binding

无法将 access_token 传递给 Reactjs 中的端点