【发布时间】:2020-06-26 12:42:09
【问题描述】:
再次编辑以解释=== 比较对象的内存位置(Why are two identical objects not equal to each other?),这就是为什么useEffect() 一次又一次地运行...我想我现在已经对其进行了排序,但将离开在这里发帖暂时没有答案,以防我说的是绝对的胡言乱语,有人想纠正我:)
--- 第二次编辑结束----
我已经编辑了我的Routes const 以将不同的sessions 记录到控制台。如您所见,它们是平等的,但由于某种原因,计算机似乎不这么认为。有谁知道为什么???
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);
----- 编辑结束-------
我在网上找到了一个tutorial 来帮助我管理用户会话,但我一直在重新渲染组件时遇到问题,除非我取出 useEffect 依赖项。我已经记录了 session 变量的值和类型,但它没有改变,所以我不明白为什么重新渲染不断发生。任何帮助将不胜感激。
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());
【问题讨论】:
-
你确定是什么原因造成的吗?
-
不,不是。我所知道的是,如果我删除
session并只保留[],这东西就不会渲染到日落中。 -
哈哈。我猜会话是一个对象,你怎么知道它没有改变?也许里面有一个正在改变的时间戳?
-
是的,它是一个对象。我还不能登录所以对象仍然只是
{}。
标签: reactjs react-hooks use-effect