Relatively new to React. I am trying to build a login function for a web app. (In React) I want to require a user to login before having access to internal pages and functions. (As that user data will be linked to what they do, see, etc…)
I want to setup “user” as a global struct/object I can refer to for various functions – and on login, pass the “user data” – (a struct I have set manually now for testing – but will eventually be returned from the login api) to the dispatch, which should update the “user state” with all pertinent information. When I do – I receive the following error:
Objects are not valid as a React child (found: object with keys {esid, uuid, status...
The error is happening in AuthProvider.(Code listed last) To be complete though, here is the code that gets there, as I suspect that it may be influencing this error(?):
In the App.js, I have an wrapper around the pages… with a around the pages that require login.
NOTE: For testing, I am using a “FakeUser”. This will be replaced when I integrate the API for login credential verification.
Full code:
App.js
export default function App() {
return (
<div className="App">
<AuthProvider>
<LocationsProvider>
<StoriesProvider>
<BrowserRouter>
<Routes>
<Route index element={<Login />} />
<Route
path="/"
element={
<ProtectedRoute>
<Route path="home" element={<Homepage />} />
<Route path="locations" element={<Locations />} />
<Route path="locations/:id" element={<LocationEdit />} />
<Route path="locationnew" element={<LocationNew />} />
<Route path="memories" element={<Memories />} />
<Route path="connections" element={<Connections />} />
<Route path="story" element={<Story />} />
</ProtectedRoute>
}
></Route>
<Route path="*" element={<PageNotFound />} />
</Routes>
</BrowserRouter>
</StoriesProvider>
</LocationsProvider>
</AuthProvider>
</div>
Protected Route
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
function ProtectedRoute({ children }) {
const { isAuthenticated } = useAuth();
const navigate = useNavigate();
useEffect(
function () {
if (!isAuthenticated) navigate("/");
},
[isAuthenticated, navigate]
);
return isAuthenticated ? children : null;
}
export default ProtectedRoute;
Login Code
export default function Login() {
// PRE-FILL FOR DEV PURPOSES
const [email, setEmail] = useState("[email protected]");
const [password, setPassword] = useState("myfakepassword");
const { login, isAuthenticated } = useAuth();
const navigate = useNavigate();
function handleSubmit(e) {
e.preventDefault();
console.log("Logging in...");
if (email && password) login(email, password);
}
useEffect(
function () {
if (isAuthenticated) navigate("/home", { replace: true });
},
[isAuthenticated]
);
return (
<main className={styles.login}>
<form className={styles.form} onSubmit={handleSubmit}>
<div className={styles.row}>
<label htmlFor="email">Email address</label>
<input
type="email"
id="email"
onChange={(e) => setEmail(e.target.value)}
value={email}
/>
</div>
<div className={styles.row}>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
onChange={(e) => setPassword(e.target.value)}
value={password}
/>
</div>
<div>
<Button type="primary">Login</Button>
</div>
</form>
</main>
);
}
AuthProvider:
import { createContext, useContext, useReducer } from "react";
const AuthContext = createContext();
const initialState = {
user: null,
isAuthenticated: false,
};
function reducer(state, action) {
switch (action.type) {
case "login":
return { ...state, user: action.payload, isAuthenticated: true };
case "logout":
return { ...state, user: null, isAuthenticated: false };
default:
throw new Error("Unknown action");
}
}
const FAKE_USER = {
esid: "1",
uuid: "11111111-0000-2222-3333333333333333",
status: "1",
firstName: "Test",
lastName: "User",
screenname: "TestUser01",
profilepic: "avatar.jpg",
email: "[email protected]",
};
function AuthProvider({ children }) {
const [{ user, isAuthenticated }, dispatch] = useReducer(
reducer,
initialState
);
function login(email, password) {
console.log(FAKE_USER);
//API Connectivity and verification will go here...
//payload is causing ERROR
if (email === "[email protected]" && password === "myfakepassword")
dispatch({ type: "login", payload: FAKE_USER });
}
function logout() {
dispatch({ type: "logout" });
}
return (
<AuthContext.Provider value={{ user, isAuthenticated, login, logout }}>
{children}
</AuthContext.Provider>
);
}
function useAuth() {
const context = useContext(AuthContext);
if (context === undefined)
throw new Error("AuthContext was used outside AuthProvider");
return context;
}
export { AuthProvider, useAuth };