我正在尝试利用 redux-sagas 框架内的 firebase observable,但如果没有 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')
}
});
}
由于未定义“回调”,因此失败。我本质上是试图让观察者传递给传奇,但它不起作用。我的解决方法是将完整的 firebase auth 对象传递给我的登录/注销传奇,然后在其中创建观察者。这可行,但看起来像是一个黑客。任何帮助将不胜感激。
最佳答案
我认为您实际上并未将 observer
集成到代码片段中的 saga
中。它适用于console.log b/c,这是一个同步函数,但您不能从该回调中产生任何内容,因为它的上下文与生成器
。这会让您失去很多sagas
实用程序(如果它能正常工作的话)。
我必须让这个在我的项目中发挥作用,我能做的最好的事情是受到 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
进行路由更改,如下所示: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)) } }
关于reactjs - 将观察者传递给 redux-sagas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39503343/