簡體   English   中英

為什么我的 redux 動作會觸發兩次,我該如何解決?

[英]Why is my redux action firing twice and how can i fix that?

我是 redux 的完整初學者,我正在嘗試創建 discord 克隆。 我正在嘗試使用帶有 firebase 的谷歌身份驗證並使用 redux 來保存 state 來創建登錄功能。 但是,每當我登錄或注銷時,該操作都會觸發兩次,我不確定為什么。 這是反應開發工具中顯示的內容:

redux 開發工具跟蹤 1

redux 開發工具跟蹤 2

這是我的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM