- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们有 UserContext
设置我们可以在整个应用程序中使用的用户对象。我们的 UserContext
每次都会继续执行,即使依赖关系没有改变,也不需要进行 api 调用。
import React, { useState, useEffect } from 'react'
import APIService from './utils/APIService';
import { getCookies } from './utils/Helper';
const UserContext = React.createContext();
const UserContextProvider = (props) => {
const [token, setToken] = useState(getCookies('UserToken'));
const [user, setUser] = useState(null);
useEffect(() => {
console.log('Inside userContext calling as token ', token)
fetchUserInfo();
}, [token]);
const fetchUserInfo = async() => {
if (token) {
let userRes = await APIService.get(`/user?token=${token}`);
console.log('User route called')
setUser(userRes.data);
}
}
/*
If user logoff or login, update token from child component
*/
const refreshToken = (newToken) => {
//token = newToken;
setToken(newToken);
fetchUserInfo()
}
return (
<UserContext.Provider value={{user, token, refreshToken}}>
{props.children}
</UserContext.Provider>
);
}
export { UserContextProvider, UserContext }
每当我们在我们的 React 应用程序中导航到不同的页面时,我们都会看到每次都调用“用户”路由,即使 token 没有更新。我们的 token 仅在用户注销时更改。
我们的 AppRouter 如下所示;
import React from 'react';
import AppRouter from "./AppRouter";
import { Container } from 'react-bootstrap';
import Header from './components/Header';
import { ToastProvider, DefaultToastContainer } from 'react-toast-notifications';
import 'bootstrap/dist/css/bootstrap.css';
import './scss/styles.scss';
import { UserContextProvider } from './UserContextProvider';
export default function App() {
const ToastContainer = (props) => (
<DefaultToastContainer
className="toast-container"
style={{ zIndex:100,top:50 }}
{...props}
/>
);
return (
<UserContextProvider>
<ToastProvider autoDismiss={true} autoDismissTimeout={3000} components={{ ToastContainer }}>
<Container fluid>
<Header />
<AppRouter />
</Container>
</ToastProvider>
</UserContextProvider>
)
}
这是我们的内部应用程序,因此我们希望用户登录 30 天,他们不必每次都保持登录状态。因此,当用户第一次登录时,我们为他们创建一个 token 并将该 token 保存在 cookie 中。因此,如果用户关闭浏览器并再次回来,我们会检查 cookie 中的 token 。如果 token 存在,我们调用 API 来获取用户信息并在我们的上下文中设置用户。这是不起作用的部分,它在导航到应用程序中的每个路由期间不断调用我们的用户 api。
这是我们的 login.js
import React, { useState, useContext } from 'react';
import { setCookies } from '../../utils/Helper';
import APIService from '../../utils/RestApiService';
import { UserContext } from '../../UserContextProvider';
import queryString from 'query-string';
import './_login.scss';
const Login = (props) => {
const [email, setEmail] = useState(null);
const [password, setPassword] = useState(null);
const [error, setError] = useState(null);
const { siteId } = props;
const { refreshToken} = useContext(UserContext);
const onKeyPress = (e) => {
if (e.which === 13) {
attemptLogin()
}
}
let params = queryString.parse(props.location.search)
let redirectTo = "/"
if (params && params.redirect)
redirectTo = params.redirect
const attemptLogin = async () => {
const payload = {
email: email,
password: password,
siteid: siteId
};
let response = await APIService.post('/login', payload);
console.log('response - ', response)
if (response.status === 200) {
const { data } = response;
setCookies('UserToken', data.token);
refreshToken(data.token)
window.location.replace(redirectTo);
}
else {
const { error } = response.data;
setError(error);
}
}
const renderErrors = () => {
return (
<div className="text-center login-error">
{error}
</div>
)
}
return (
<div className="login-parent">
<div className="container">
<div className="login-row row justify-content-center align-items-center">
<div className="login-column">
<div className="login-box">
<form className="login-form form">
<h3 className="login-form-header text-center">Login</h3>
<div className="form-group">
<label>Email:</label>
<br/>
<input
onChange={e => setEmail(e.target.value)}
placeholder="enter email address"
type="text"
onKeyPress={onKeyPress}
className="form-control"/>
</div>
<div className="form-group">
<label>Password:</label>
<br/>
<input
onChange={e => setPassword(e.target.value)}
placeholder="enter password"
type="password"
className="form-control"/>
</div>
<div className="form-group">
<button
className="btn btn-secondary btn-block"
onClick={attemptLogin}
type="button">
Login
</button>
</div>
{error ? renderErrors() : null}
</form>
</div>
</div>
</div>
</div>
</div>
)
}
export default Login;
我们的 userContext 如下所示
import React, { useState, useEffect } from 'react'
import APIService from './utils/APIService';
import { getCookies } from './utils/Helper';
const UserContext = React.createContext();
const UserContextProvider = (props) => {
const [token, setToken] = useState(getCookies('UserToken'));
const [user, setUser] = useState(null);
useEffect(() => {
if (!token) return;
console.log('Inside userContext calling as token ', token)
fetchUserInfo();
}, [token]);
const fetchUserInfo = async() => {
if (token) {
let userRes = await APIService.get(`/user?token=${token}`);
console.log('User route called')
setUser(userRes.data);
}
}
/*
If user logoff or login, update token from child component
*/
const refreshToken = (newToken) => {
//token = newToken;
setToken(newToken);
fetchUserInfo()
}
return (
<UserContext.Provider value={{user, token, refreshToken}}>
{props.children}
</UserContext.Provider>
);
}
export { UserContextProvider, UserContext }
我们的 getCookies 函数使用 universal-cookies 包简单地读取 cookie
export const getCookies = (name) => {
return cookies.get(name);
};
最佳答案
所以我尝试使用 CodeSandbox 重现您的问题,这些是我基于您的代码的发现:
您的上下文有一个 useEffect
,它依赖于 token
。当您调用 refreshToken
时,您更新了 token
,它会自动触发 useEffect
并调用 fetchUserInfo
。所以你不需要在 refreshToken
中的 setToken
之后调用 fetchUserInfo
。你的上下文看起来像:
const UserContext = React.createContext();
const UserContextProvider = (props) => {
const [token, setToken] = useState(getCookies("UserToken"));
const [user, setUser] = useState(null);
useEffect(() => {
console.log("Inside userContext calling as token ", token);
fetchUserInfo();
}, [token]);
const fetchUserInfo = async () => {
if (token) {
let userRes = await APIService.get(`/user?token=${token}`);
console.log('User route called')
setUser(userRes.data);
}
};
const refreshToken = (newToken) => {
setToken(newToken);
};
return (
<UserContext.Provider value={{ user, token, refreshToken }}>
{props.children}
</UserContext.Provider>
);
};
export { UserContextProvider, UserContext };
现在开始你的路由,因为你没有包含 AppRouter
的代码 我不得不做出一个假设你使用 react-router
带有 Switch
组件。 (如 CodeSandbox 所示)。
我在您的 Login
组件中看到一行是 window.location.replace(redirectTo);
。当您这样做时,整个页面都会刷新(重新加载?)并且 React 会触发重新渲染,这就是为什么我认为您的上下文方法会再次触发。
而是使用 react-router
中的 history
API (同样,我的假设) 就像这样,
let history = useHistory();
history.push(redirectTo);
如果你想玩的话,这里是沙盒:
关于reactjs - useEffect 每次都会执行,即使依赖关系没有改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68005144/
我在 gobject 上阅读了一个维基百科页面,上面写着, Depending only on GLib and libc, GObject is a cornerstone of GNOME and
如何注册一个依赖属性,其值是使用另一个依赖属性的值计算的? 由于 .NET 属性包装器在运行时被 WPF 绕过,因此不应在 getter 和 setter 中包含逻辑。解决方案通常是使用 Proper
我一直在尝试将 ActionbarSherlock maven 依赖项添加到我的项目中 com.actionbarsherlock library 4.2.0 在我的 po
http://tutorials.jenkov.com/ood/understanding-dependencies.html#whatis说(强调我的): Whenever a class A us
我对所有这些魔法有点不清楚。 据我了解,依赖属性是从 DependencyObject 继承的,因此存储值: 如果分配了值(在本地字典中),则在实例本身中 或者如果未指定值,则从指向父元素的链接中获取
我刚刚更新了在 ASP.NET Framework 4.5.2 版上运行的 MVC Web 应用程序。我正在使用 Twilio 发送 SMS 消息: var twilio = new TwilioRe
我刚刚发现了一件令人生畏的事情。 spring 依赖坐标有两个版本。 项目依赖于 spring mvc 和 spring flow。有两组并行的依赖项。 Spring MVC 具有以下方案的依赖项
我正在尝试包含 的 maven 依赖项 org.jacorb jacorb 2.3.1 依赖已解决,但它导致另一个依赖 picocontainer 出现问题: [ERROR
我正在尝试在 Haskell 项目中包含特定版本的库。该库是住宿加早餐型的(用于 martix 操作),但我需要特定的 0.4.3 版本,该版本修复了乘法实现的错误。 所以,我的 stack.yaml
有谁知道如何制作依赖的 UIPickerView.例如,当我选择组件一的第 2 行时,组件二的标题会发生变化吗? 我在互联网上查找过,没有真正的答案,我尝试过使用 if 和 switch 语句,但它们
我正在编写一个用于验收测试的项目,由于各种原因,这依赖于另一个打包为 WAR 的项目。我已成功使用 maven-dependency-plugin 解压 WAR,但无法让我的项目包含解压的 WEB-I
或多或少我在 session 上大量构建我的网站(特别是重定向用户等),我很好奇这是否是一种危险的做法。禁用浏览器 cookie 保存的用户的大致比例是多少?我愿意接受任何建议:) 谢谢 最佳答案 s
开始玩 Scala futures,我被依赖的 futures 困住了。 让我们举个例子。我搜索地点并获得 Future[Seq[Place]]。对于这些地点中的每一个,我搜索最近的地铁站(该服务返回
或多或少我在 session 上大量构建我的网站(特别是重定向用户等),我很好奇这是否是一种危险的做法。禁用浏览器 cookie 保存的用户的大致比例是多少?我愿意接受任何建议:) 谢谢 最佳答案 s
我有一个二进制文件,需要一些 *.so 文件才能执行。现在,当我尝试在一些旧机器上执行它时,它会显示 /lib/libc.so.6: version `GLIBC_2.4' not found 如何将
我尝试使用 Dygraph 来表示图表,我在 https://github.com/danvk/dygraphs 中找到了代码,但是它有太多的依赖文件,我觉得很烦人。是否有一个文件可以容纳所有必需的
我正在处理一个 javascript 文件,该文件 a) 声明一个具有函数的对象,并且 b) 使用它期望在外部声明的散列调用该对象的 init 函数。我的 Jasmine 规范提示它找不到哈希,因为它
最近我一直在学习 Angular 并且进展顺利,但是关于依赖注入(inject)的一些事情我仍然不清楚。 是否有任何理由在我的 app.js 文件中声明我的应用程序的其他部分(服务、 Controll
考虑一个名为 foo 的表,它有 id (PRIMARY & AUTO_INCREMENT) 列。我正在向该表中插入一行,挑战从此时开始。 $db->query("INSERT INTO `foo`
我正在使用级联下拉 jquery 插件。 (https://github.com/dnasir/jquery-cascading-dropdown) 我有两个下拉菜单。 “客户端”和“站点”。 根据您
我是一名优秀的程序员,十分优秀!