【发布时间】:2019-10-24 06:27:41
【问题描述】:
我的应用需要在用户登录时执行一系列 Redux 调度。这些调度必须在用户被重定向到基于商店状态的页面之前完成。通过一些调试,我发现似乎在用户登录并触发 Firebase 的 onAuthStateChanged 侦听器后,页面会自动将用户重定向到登录页面(然后由 react-router 重定向)而不是当我声明重定向时。 有没有办法防止这种行为?
起初,我认为重定向是由调度触发的,但经过一些调试后,我将行为范围缩小到身份验证更改。一旦用户已经通过身份验证并执行页面刷新,我就可以验证一切是否按预期工作。
// A bunch of imports before this
const store = configureStore()
const jsx = (
<Provider store={store}>
<AppRouter />
</Provider>
)
let hasRendered = false
const renderApp = () => {
if (!hasRendered) {
store.dispatch(setApi()).then(() => {
ReactDOM.render(jsx, document.getElementById('app'))
})
hasRendered = true
}
}
ReactDOM.render(<LoadingPage />, document.getElementById('app'))
firebase.auth().onAuthStateChanged(async (user) => {
if (user) {
console.log('logged in')
store.dispatch(login(user.uid))
await store.dispatch(startGetProfiles(user.uid))
const profiles = store.getState().profiles
const selectedCharacterId = localStorage.getItem('selectedCharacterId')
const profileId = selectedCharacterId || profiles.length === 1 && profiles[0].id
if (profileId) {
await store.dispatch(startSetProfile(user.uid, profileId))
}
const profile = store.getState().profile
renderApp()
if (!!profile.id) {
history.push('/profile')
} else if (profiles.length > 0) {
history.push('/select')
} else {
history.push('/create')
}
} else {
console.log('logged out')
store.dispatch(logout())
renderApp()
history.push('/')
}
})
我希望页面重定向仅在我使用 history.push('/somepage') 时发生,但重定向会在用户登录后立即触发。
【问题讨论】:
-
“Firebase onAuthStateChange 是否应该自动触发页面重定向?”没有。它不是,也不是。如果您在
if (user) {上设置断点,当您在调试器中运行代码时会触发它吗?如果是这样,当您逐步执行该方法的其余部分时,哪一行没有按照您的预期执行? -
Welp,我刚刚学会了如何实际调试,非常感谢。在深入研究之后,似乎页面刷新是在
store.dispatch(login(user.uid))调用之后立即发生的。此外,事实证明 else 块中的history.push('/')调用不是必需的,因为页面在store.dispatch(logout())调用之后重定向,这似乎加强了我的怀疑,即 firebase 在执行登录/注销后触发页面刷新过程。 -
这不太可能,但当然也不是不可能。您可以尝试在 jsbin 之类的网站上仅使用 Firebase 身份验证 SDK 重现它,以便我看看吗?请参阅how to create a minimal, complete, verifiable example,了解有关最小化重现问题所需代码的更多提示,以及为什么这很重要。
标签: reactjs firebase react-redux firebase-authentication react-router-v4