我正在为我的应用程序中的受保护路由探索基于 authContext 的登录方法。我创建了以下配置来支持它:
import React, { createContext, useContext, useReducer } from "react";
import AuthReducer from "./AuthReducer";
const AuthStateContext = createContext();
const AuthDispatchContext = createContext();
export const useAuthState = () => useContext(AuthStateContext);
export const useAuthDispatch = () => useContext(AuthDispatchContext);
export const AuthProvider = ({ children }) => {
const [state, dispatch] = useReducer(AuthReducer, {
isAuthenticated: false,
token: null,
});
return (
<AuthStateContext.Provider value={state}>
<AuthDispatchContext.Provider value={dispatch}>
{children}
</AuthDispatchContext.Provider>
</AuthStateContext.Provider>
);
};
const initialState = {
isAuthenticated: false,
token: null,
};
const AuthReducer = (state = initialState, action) => {
switch (action.type) {
case "LOGIN":
return {
...state,
isAuthenticated: true,
token: action.payload.token,
};
case "LOGOUT":
return {
...state,
isAuthenticated: false,
token: null,
};
default:
return state;
}
};
export default AuthReducer;
import React from "react";
import { Navigate, Outlet } from "react-router-dom";
import { useAuthState } from "./AuthContext";
export default function ProtectedRoute() {
const { isAuthenticated } = useAuthState();
return isAuthenticated ? <Outlet /> : <Navigate to="/" />;
}
import React from "react";
import ReactDOM from "react-dom/client";
import { AuthProvider } from "./context/AuthContext";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<AuthProvider>
<App />
</AuthProvider>
</React.StrictMode>
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import ProtectedRoute from "./context/ProtectedRoute";
import { AuthProvider } from "./context/AuthContext";
import HomePage from "./home/HomePage";
import ErrorPage from "./errorPage/ErrorPage";
import LoginComponent from "./auth/login/LoginComponent";
import LandingPage from "./landingPage/LandingPage";
const App = () => {
return (
<AuthProvider>
<BrowserRouter>
<Routes>
<Route exact path="/" element={<HomePage />} />
<Route path="/login" element={<LoginComponent />} />
<Route element={<ProtectedRoute />}>
<Route path="/dashboard" element={<LandingPage />} />
</Route>
<Route path="*" element={<ErrorPage />} />
</Routes>
</BrowserRouter>
</AuthProvider>
);
};
export default App;
用于收集用户名和密码并执行登录操作的登录组件如下:
import { useAuthDispatch } from "../../context/AuthContext";
import axios from "axios";
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
const LoginComponent = () => {
const navigate = useNavigate();
const authDispatch = useAuthDispatch;
const [error, setError] = useState(false);
const handleLogin = async (e) => {
e.preventDefault();
// API variable structure
const loginInputs = {
email,
password,
};
try {
const config = {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
};
const { data } = await axios.post(
http://x.x.x.x/api/login,
loginInputs,
config
);
if (data) {
const token = data.token;
authDispatch({ type: "LOGIN", payload: { token } });
navigate("/dashboard");
} else {
setError("Invalid username or password");
}
} catch (error) {
setError(true);
}
};
return (
// Some form code to take the username and password
);
};
export default LoginComponent;
我正确获取了令牌,但不知何故登录无法正常工作。 AuthContext 似乎存在一些问题。 authDispatch 无法正确传递有效负载。
LoginComponent.jsx
文件中有一个拼写错误:
const authDispatch = useAuthDispatch;
将其更改为以下内容后,一切开始正常工作。
const authDispatch = useAuthDispatch();