将观察者传递到 redux-sagas
Passing observer into redux-sagas
我正在尝试利用 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')
}
});
}
由于 'callback' 未定义,此操作失败。我本质上是在试图说服观察者将其传递给 sagas,但它不起作用。我的解决方法是将完整的 firebase auth 对象传递给我的 login/logout saga,然后在其中创建观察者。那行得通,但似乎很hack。任何帮助将不胜感激。
您似乎打算将 callback
作为 authChanged
的参数,但 authChanged
目前没有参数。这可能是您想要做的:
authChanged: (callback) => {
return firebaseAuth.onAuthStateChanged(callback);
}
我不确定我是否理解柯里化观察者的意思,但您也可以这样做来柯化 firebase 方法以用作您的方法:
{
authChanged: ::firebaseAuth.onAuthStateChanged,
}
我认为您实际上并没有将 observer
整合到代码段中的 saga
中。它适用于 console.log
b/c 这是一个同步函数,但您不能 yield
来自该回调的任何内容,因为它的上下文与 generator
的上下文是分开的。这剥夺了你很多 sagas
实用程序,如果它工作 @ all.
我必须在我的项目中使用它,而我能做的最好的是受到 this project and the architecture in this starter-kit 的启发。
基本上就是几步。
将您的观察者包装在接受 dispatch
和 returns 一个 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))
}
}
我正在尝试利用 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')
}
});
}
由于 'callback' 未定义,此操作失败。我本质上是在试图说服观察者将其传递给 sagas,但它不起作用。我的解决方法是将完整的 firebase auth 对象传递给我的 login/logout saga,然后在其中创建观察者。那行得通,但似乎很hack。任何帮助将不胜感激。
您似乎打算将 callback
作为 authChanged
的参数,但 authChanged
目前没有参数。这可能是您想要做的:
authChanged: (callback) => {
return firebaseAuth.onAuthStateChanged(callback);
}
我不确定我是否理解柯里化观察者的意思,但您也可以这样做来柯化 firebase 方法以用作您的方法:
{
authChanged: ::firebaseAuth.onAuthStateChanged,
}
我认为您实际上并没有将 observer
整合到代码段中的 saga
中。它适用于 console.log
b/c 这是一个同步函数,但您不能 yield
来自该回调的任何内容,因为它的上下文与 generator
的上下文是分开的。这剥夺了你很多 sagas
实用程序,如果它工作 @ all.
我必须在我的项目中使用它,而我能做的最好的是受到 this project and the architecture in this starter-kit 的启发。
基本上就是几步。
将您的观察者包装在接受
dispatch
和 returns 一个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)) } }