下拉菜单中有一个注销按钮,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 中的导航
我查看了多个与同一问题相关的帖子,但他们的方法并没有解决我的问题。
现在有效。我删除了 Logout.jsx 中的链接并更改了
注销启动(调度);
与
注销(调度); //与 ApiCall.js 中一样
然后导航工作