使用 useContext() 注销并在成功注销后导航到登录页面 // react-router-dom v6.8.2 //react.js netflix clone {new to react}

问题描述 投票:0回答:1

下拉菜单中有一个注销按钮,Logout.jsx 在顶部栏组件下的下拉菜单中被称为组件。我检查了 console.log ;所有调用都已完成,本地存储“用户”已清除但仍导航到登录,不会以某种方式执行。

注销.jsx

import { useContext, useEffect, useState} from "react";
import { Link, useNavigate } from "react-router-dom";
import { logout} from "../../context/authContext/ApiCalls";
import { logoutInitiate } from "../../context/authContext/AuthAction";
import { AuthContext } from "../../context/authContext/AuthContext";

export default function Logout() {
  const { isFetching , dispatch } = useContext(AuthContext);
  const navigate = useNavigate();

  const handleLogout = (e) => {
    e.preventDefault();
    navigate("/login");
   logoutInitiate(dispatch);
  };
   
  return (
    <div className="options">
        <Link to="/login">
            <span onClick={handleLogout} disabled={isFetching}>Logout</span>
        </Link> 
    </div>
  )
}

AuthContext.js

import AuthReducer from "./AuthReducer";
import {createContext, useEffect, useReducer } from "react";

const INITIAL_STATE = {
    user: JSON.parse(localStorage.getItem("user")) || null,
    isFetching:false,
    error:false
};

export const AuthContext = createContext(INITIAL_STATE);

export const AuthContextProvider = ({children}) => {
    const [state,dispatch] = useReducer(AuthReducer, INITIAL_STATE);
    
    useEffect(() => {
        localStorage.setItem("user", JSON.stringify(state.user))
    },[state.user])

    return (
        <AuthContext.Provider 
         value={{
            user:state.user,
            isFetching: state.isFetching,
            error: state.error,
            dispatch
            }}
        >
          {children}
        </AuthContext.Provider>
    )
};

AuthReducer.js:

const AuthReducer = (state,action) => {
    switch(action.type){
      case "LOGIN_START":
         return{
           user:null,
           isFetching:true,
           error:false 
        };
        case "LOGIN_SUCCESS":
         return{
           user: action.payload,
           isFetching:false,
           error:false 
        };
        case "LOGIN_FAILURE":
         return{
           user:null,
           isFetching:false,
           error:true
        };
        case "LOGOUT":
         return{
           user:null,
           isFetching:false,
           error:false
        };
        default:
         return {...state};
    }
}

export default AuthReducer;

authAction.js:

export const loginStart = () => ({
  type: "LOGIN_START",
});

export const loginSuccess = (user) => ({
   type: "LOGIN_SUCCESS",
   payload: user, 
});

export const loginFailure = () => ({
    type: "LOGIN_FAILURE",
});

//logout
export const logoutInitiate = () => ({
  type: "LOGOUT",
});`

ApiCalls.js

import axios from "axios";
import { loginFailure, loginStart, loginSuccess ,logoutInitiate} from "./AuthAction";

export const login = async (user, dispatch) => {
  dispatch(loginStart);
  try{
    const res = await axios.post("auth/login", user);
    res.data.isAdmin && dispatch(loginSuccess(res.data))
  }catch(err){
    dispatch(loginFailure);
  }
};

export const logout = (dispatch) => {
  try{
    localStorage.removeItem("user") && dispatch(logoutInitiate()) ;
  }catch(err){
    console.log(err)
  }
};

App.js

import "./app.css"
import {BrowserRouter as Router, Routes, Route, Navigate} from "react-router-dom";
import Layout from "./components/layout/Layout";
import Home from "./pages/home/Home";
import User from "./pages/user/User";
import UserList from "./pages/userList/UserList";
import NewUser from "./pages/newUser/NewUser";
import ProductList from "./pages/productList/ProductList";
import Product from "./pages/product/Product";
import NewProduct from "./pages/newProduct/NewProduct";
import Login from "./pages/login/Login";
import { useContext } from "react";
import { AuthContext } from "./context/authContext/AuthContext";


function App() {
  const {user} = useContext(AuthContext);
  //console.log(user)

  return (
  
    <Router>
      <Routes>
         {user && (
             <Route path="/" element={<Layout />}>
                <Route path="/" element={<Home/>} />
                <Route path="/users" element={<UserList/>} />
                <Route path="/user/:userId" element={<User/>} />
                <Route path="/newUser" element={<NewUser/>} />
                <Route path="/movies" element={<ProductList/>} />
                <Route path="/product/:productId" element={<Product/>} />
                <Route path="/newProduct" element={<NewProduct/>} />
              </Route>
          
          )}
        <Route path="/login" element={user ? <Navigate to="/"/> : <Login/>} />
      </Routes>
    </Router>
  );
}

export default App;
  • 尝试使用像

    navigate("/otherpage")
    这样的导航=>这以某种方式起作用但是当我使用
    navigate("/login")

    时它不起作用
  • 尝试使用 useState 和 useEffect 来调用 Logout.jsx 中的导航

  • 我查看了多个与同一问题相关的帖子,但他们的方法并没有解决我的问题。

reactjs react-hooks react-router react-context logout
1个回答
0
投票

现在有效。我删除了 Logout.jsx 中的链接并更改了

注销启动(调度);

注销(调度); //与 ApiCall.js 中一样

然后导航工作

© www.soinside.com 2019 - 2024. All rights reserved.