[英]Why is my redux action firing twice and how can i fix that?
我是 redux 的完整初學者,我正在嘗試創建 discord 克隆。 我正在嘗試使用帶有 firebase 的谷歌身份驗證並使用 redux 來保存 state 來創建登錄功能。 但是,每當我登錄或注銷時,該操作都會觸發兩次,我不確定為什么。 這是反應開發工具中顯示的內容:
這是我的 store.js 代碼
import { configureStore } from '@reduxjs/toolkit';
import userReducer from '../components/Reducers/userSlice';
import appReducer from '../components/Reducers/appSlice';
import { composeWithDevTools } from 'redux-devtools-extension';
const composeEnhancers = composeWithDevTools({trace: true});
export const store = configureStore({
reducer: {
user: userReducer,
app: appReducer,
},
});
這是我的 userSlice.js 代碼:
import { createSlice } from '@reduxjs/toolkit';
export const userSlice = createSlice({
name: 'user',
initialState: {
user: null,
},
reducers: {
login: (state, action ) => {
state.user = action.payload;
},
logout: (state) => {
state.user = null;
}
},
});
export const { login, logout } = userSlice.actions;
export const selectUser = (state) => state.user.user;
export default userSlice.reducer;
這些是 app.js 中的相關代碼行
import { login, logout, selectUser } from './components/Reducers/userSlice'
import Login from './components/Login/Login';
import { auth } from './firebase';
function App() {
//allows us to shoot things into the datalayer
const dispatch = useDispatch()
//selects user from the data layer
const user = useSelector(selectUser)
useEffect(() => { //listens for change in user and reloads accordingly
auth.onAuthStateChanged((authUser) => {
if (authUser){
//user log in
dispatch(
login({
uid: authUser.uid,
photo: authUser.photoURL,
email: authUser.email,
displayName: authUser.displayName
}))
} else {
//user log out
dispatch(logout())
}
})
}, [dispatch])
return (
<div className="app">
{user ? (
<>
<Sidebar/>
<Chat />
</>
) : (
<Login />
)}
</div>
);
}
export default App;
這就是我稱之為注銷 function 的地方
<div className="sidebar__profile">
<Avatar onClick={() => auth.signOut()} src={user.photo} />
<div className="sidebar__profileInfo">
<h3>{user.displayName}</h3>
<p>#{user.uid.substring(0, 5)}</p>
</div>
<div className="sidebar__profileIcons">
<MicIcon />
<SettingsIcon />
<HeadsetIcon />
</div>
</div>
這是我登錄的地方
import { Button } from '@mui/material'
import React from 'react'
import { auth, provider, signInWithPopup } from '../../firebase'
import './Login.css'
function Login() {
const signIn = () => {
//google authentication stuff
signInWithPopup(auth, provider)
.catch((error) => {
alert(error.message)
})
}
return (
<div className='login'>
<div className="login__logo">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Discord_white_D.svg/91px-Discord_white_D.svg.png?20180117191712" alt="Disclone logo" />
</div>
<Button onClick={signIn}>Sign In</Button>
</div>
)
}
export default Login
您很可能兩次訂閱auth.onAuthStateChange()
。 This function returns an unsubscribe function which should be called to clean up ( https://firebase.google.com/docs/reference/js/v8/firebase.auth.Auth#returns-firebase.unsubscribe_1 ). useEffect 可以將 function 作為返回值,在它再次運行或完成之前將被調用。
更改您的useEffect()
以捕獲返回的取消訂閱 function 然后返回:
useEffect(() => { //listens for change in user and reloads accordingly
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser){
//user log in
dispatch(
login({
uid: authUser.uid,
photo: authUser.photoURL,
email: authUser.email,
displayName: authUser.displayName
}))
} else {
//user log out
dispatch(logout())
}
})
return unsubscribe
}, [dispatch])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.