javascript - 当前用户的数据不会在没有刷新的情况下显示,MERN 堆栈
问题描述
下午好/早上好!
我已经为此工作了几天,似乎无法弄清楚这一点。它使用 json 服务器和 localhost 在本地运行完美。现在它已部署到heroku,我遇到了这个问题。
问题:如果我登录用户,除非我刷新,否则它不会显示任何内容。如果我最近有其他用户登录,它将显示他们的数据,除非我点击刷新。这只是为了测试,我在我的电脑上做所有这些。
我尝试了什么几乎所有我能想到的。查看网络控制台以查看获取内容的顺序,我很确定我看到了问题。
当我第一次登录时,我在网络选项卡中得到这个订单
登录
令牌有效
得到
用户
当我刷新我得到
轮廓
(heroku 的静态块)
反应开发工具后端
令牌有效
得到
用户
我对此很陌生,但是在我的用户数据的获取请求之后看到用户的获取请求导致了这个问题。当我刷新时,顺序无关紧要,因为我仍然登录。这就是我的逻辑。
所以这是我的相关组件代码
应用程序.js
import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Profile from "./Components/Profile";
import Main from "./Components/Main";
import UserContext from "./Components/UserContext";
import SearchResults from "./Components/SearchResults";
function App() {
const [userData, setUserData] = React.useState({
token: null,
user: null,
});
return (
<div className="App">
<UserContext.Provider value={{ userData, setUserData }}>
<Router>
<Switch>
<Route exact path="/" component={Main} />
<Route path="/profile" component={Profile} />
<Route path="/search" component={SearchResults} />
</Switch>
</Router>
</UserContext.Provider>
</div>
);
}
export default App;
登录.jsx
... the code for my get request
const handleSubmit = async (e) => {
e.preventDefault();
try {
const loginUser = { email, password };
const loginRes = await axios.post("/users/login", loginUser, authToken);
setUserData({
token: loginRes.data.token,
user: loginRes.data,
});
console.log(loginRes.data.token)
localStorage.setItem("auth-token", loginRes.data.token);
history.push("/profile");
} catch (err) {
err.response.data.msg && setError(err.response.data.msg);
}
};
显示记录.jsx
....
//set state for records and userData
const [newRecords, newRecordData] = React.useState([]);
const { setUserData } = React.useContext(UserContext);
....
//fetch record data
const fetchData = async () => {
const result = await axios.get("record/get", authToken);
newRecordData(result.data);
console.log(result.data)
};
// see if user is logged in already, if not set a token and userData
const checkLoggedIn = async () => {
let token = localStorage.getItem("auth-token");
if (token === null) {
localStorage.setItem("auth-token", "");
token = null;
}
const tokenRes = await axios.post("/users/tokenIsValid", null, {
headers: { "x-auth-token": token },
});
if (tokenRes.data) {
const userRes = await axios.get("/users", {
headers: { "x-auth-token": token },
});
setUserData({
token: userRes.data,
user: userRes.data,
});
}
};
React.useEffect(() => {
checkLoggedIn()
fetchData();
console.log("data");
}, []);
....
编辑:这是我的后端
用户路由.js
... relavent routes
router.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
// validate
if (!email || !password)
return res.status(400).json({ msg: "Wait... some fields are empty!" });
const user = await User.findOne({ email: email });
if (!user)
return res
.status(400)
.json({ msg: "No account with this email has been registered." });
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ msg: "Invalid credentials." });
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET);
res.json({
token,
user: {
id: user._id,
displayName: user.displayName,
},
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/tokenIsValid", async (req, res) => {
try {
const token = req.header("x-auth-token");
if (!token) return res.json(false);
const verified = jwt.verify(token, process.env.JWT_SECRET);
if (!verified) return res.json(false);
const user = await User.findById(verified.id);
if (!user) return res.json(false);
return res.json(true);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.get("/", auth, async (req, res) => {
const user = await User.findById(req.user);
res.json({
displayName: user.displayName,
id: user._id,
});
});
...
记录路由.js
... all other routes here aren't related and work fine
//get records
router.get("/get", auth, async(req,res) =>{
const records = await Record.find({ userId: req.user});
res.json(records)
})
auth.js
const jwt = require("jsonwebtoken");
const auth = (req, res, next) => {
try {
const token = req.header("x-auth-token");
if (!token)
return res
.status(401)
.json({ msg: "No authentication token, authorization denied." });
const verified = jwt.verify(token, process.env.JWT_SECRET);
if (!verified)
return res
.status(401)
.json({ msg: "Token verification failed, authorization denied." });
req.user = verified.id;
next();
} catch (err) {
res.status(500).json({ error: err.message });
}
};
module.exports = auth;
任何帮助将不胜感激。我对此感到困惑,这是我需要做的这个应用程序的最后一件事!
解决方案
我不知道这是否是最佳做法,但我根本找不到解决此问题的另一种方法。
我添加了
window.location.reload();
到 register.jsx 和 login.jsx axios 请求。我知道这会强制重新加载文档,但这只是我可以让它工作的唯一方法,经过 5 天的尝试解决这个问题,我可以接受。如果有人知道不同的方式,我全神贯注。
推荐阅读
- node.js - 使用 findOne() 时 NeDB 没有回调
- javascript - 为动态创建的按钮添加随机功能
- go - 如何在golang go-face中捕获每张脸
- typescript - TypeError:无法读取未定义的属性“已检查”
- jenkins - 是否可以看到浏览器堆栈从 Jenkins 录制视频
- java - Java 在库路径上找不到代理库 hprof
- java - Java从url获取内容
- tensorflow - Conda YML 文件提示“请添加显式 pip 依赖项”
- amazon-web-services - 在 AWS Fargate 上部署容器(如果已经有容器在运行,则需要比平时更多的时间来启动)
- python - Keras:训练对象正确移动