Edited again to explain that ===
compares the memory location of objects (Why are two identical objects not equal to each other?) which is why the useEffect()
kept running again and again and again... I think I have it sorted now but will leave the post here without an answer for a while in case I'm talking absolute gibberish and someone would like to correct me :)
--- End of second edit ----
I have edited my Routes
const to log the different sessions
to the console. As you can see, they are equal but for some reason, the computer doesn't seem to think so. Does anyone have any idea why???
edited Routes (to show the values)
const Routes = () => {
const [session, setSession] = useState(getSessionCookie());
console.log('Route session before: ', session);
useEffect(
() => {
//setSession(getSessionCookie());
const stateCookie = session;
const getCookie = getSessionCookie();
console.log('stateCookie: ', stateCookie);
console.log('getCookie: ', getCookie);
console.log('Are equal? ', stateCookie === getCookie);
},
[session]
);
console.log('Route session after: ', session);
----- End of edit -------
I found a tutorial online to assist me in managing user sessions but I keep having a problem with the re-rendering of the component unless I take out the useEffect dependency. I've logged the values and types of the session
variable but it doesn't change so I don't understand why the re-render keeps happening. Any help would be greatly appreciated.
index.js
import React, { useEffect, useState, useContext } from 'react';
import { render } from "react-dom";
import { Router, Switch, Route } from "react-router";
import { Link } from "react-router-dom";
import { createBrowserHistory } from "history";
import Cookies from "js-cookie";
import { SessionContext, getSessionCookie, setSessionCookie } from "./session";
const history = createBrowserHistory();
const LoginHandler = ({ history }) => {
const [email, setEmail] = useState("");
const [loading, setLoading] = useState(false);
const handleSubmit = async e => {
e.preventDefault();
setLoading(true);
// NOTE request to api login here instead of this fake promise
await new Promise(r => setTimeout(r(), 1000));
setSessionCookie({ email });
history.push("/");
setLoading(false);
};
if (loading) {
return <h4>Logging in...</h4>;
}
return (
<div style={{ marginTop: "1rem" }}>
<form onSubmit={handleSubmit}>
<input
type="email"
placeholder="Enter email address"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<input type="submit" value="Login" />
</form>
</div>
);
};
const ProtectedHandler = ({ history }) => {
const session = useContext(SessionContext);
if (session.email === undefined) {
history.push("/login");
}
return (
<div>
<h6>Protected data for {session.email}</h6>
<Link to="/logout">Logout here</Link>
</div>
);
};
const LogoutHandler = ({ history }) => {
useEffect(
() => {
Cookies.remove("session");
history.push("/login");
},
[history]
);
return <div>Logging out!</div>;
};
const Routes = () => {
const [session, setSession] = useState(getSessionCookie());
console.log('Routes session before: ', session);
console.log('Routes session before typeof: ', typeof session);
useEffect(
() => {
setSession(getSessionCookie());
},
[session] // <-------------- this is the dependency that seems to be causing the trouble
);
console.log('Routes session: ', session);
console.log('Routes session typeof: ', typeof session);
return (
<SessionContext.Provider value={session}>
<Router history={history}>
<div className="navbar">
<h6 style={{ display: "inline" }}>Nav Bar</h6>
<h6 style={{ display: "inline", marginLeft: "5rem" }}>
{session.email || "No user is logged in"}
</h6>
</div>
<Switch>
<Route path="/login" component={LoginHandler} />
<Route path="/logout" component={LogoutHandler} />
<Route path="*" component={ProtectedHandler} />
</Switch>
</Router>
</SessionContext.Provider>
);
};
const App = () => (
<div className="App">
<Routes />
</div>
);
const rootElement = document.getElementById("root");
render(<App />, rootElement);
session.js
import React from "react";
import * as Cookies from "js-cookie";
export const setSessionCookie = (session) => {
Cookies.remove("session");
Cookies.set("session", session, { expires: 14 });
};
export const getSessionCookie = () => {
const sessionCookie = Cookies.get("session");
if (sessionCookie === undefined) {
console.log('undefined');
return {};
} else {
return return JSON.parse(sessionCookie);
}
};
export const SessionContext = React.createContext(getSessionCookie());