代码在React 16.8上运行良好,但在> = 16.9时冻结。我查看了16.9的更改,但是当发生无限循环而不是行为的实际更改时,它提到的只是一个额外的警告,所以这不应该发生,而是这样。
将useEffect的依赖项设置为[]确实会破坏循环,但意味着代码需要修改,我不确定如何修改。
以下代码也可以在沙箱here中找到。该版本设置为16.8.4,因此不会冻结。
index.jsx
//...
import { SessionContext,getSessionCookie,setSessionCookie } from "./session";
import "./styles.css";
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 (
//...
);
};
const LogoutHandler = ({ history }: any) => {
//...
};
const ProtectedHandler = ({ history }) => {
//...
};
const Routes = () => {
const [session,setSession] = useState(getSessionCookie());
useEffect(
() => {
setSession(getSessionCookie());
},[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.ts
import React from "react";
import * as Cookies from "js-cookie";
export const setSessionCookie = (session: any): void => {
Cookies.remove("session");
Cookies.set("session",session,{ expires: 14 });
};
export const getSessionCookie: any = () => {
const sessionCookie = Cookies.get("session");
if (sessionCookie === undefined) {
return {};
} else {
return JSON.parse(sessionCookie);
}
};
export const SessionContext = React.createContext(getSessionCookie());
预期结果:应用程序在16.9中起作用,就像在16.8中一样
实际结果:由于在useEffect中存在无限循环,应用程序冻结在16.9中
错误消息:警告:超出最大更新深度。当组件在useEffect中调用setState时会发生这种情况,但useEffect要么没有依赖项数组,要么在每个渲染器上都有一个依赖项更改。