如果没有刷新、MERN堆栈,当前用户的数据将不会显示



下午好!

我已经研究了几天了,似乎无法弄清楚这个问题。它使用json服务器和localhost在本地运行非常完美。现在它被部署到heroku,我遇到了这个问题。

问题:如果我登录用户,除非我刷新,否则它不会显示任何内容。如果我最近有其他用户登录,它会显示他们的数据,除非我点击刷新。这只是为了测试,我在电脑上做这一切。

我尝试了什么我能想到的几乎都是。通过查看网络控制台来查看获取东西的顺序,我确信我看到了问题所在。

当我第一次登录时,我在网络选项卡中得到了这个订单

登录

tokenIsValid

获取

用户

当我刷新时,我得到

配置文件

(heroku的静态块(

react devtools后端

tokenIsValid

获取

用户

我对这方面还很陌生,但看到对用户的get请求出现在对我的用户数据的get请求之后,导致了这个问题。当我刷新时,顺序无关紧要,因为我仍然登录。这是我的逻辑。

这是我的相关组件的代码

App.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);
}
};

ShowRecords.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");
}, []);
....

编辑:这是我的后端

UserRoute.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,
});
});
...

RecordRoute.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天的努力,我可以接受。如果有人知道不同的方法,我会洗耳恭听。

最新更新