首页 > 解决方案 > 当前用户的数据不会在没有刷新的情况下显示,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;

任何帮助将不胜感激。我对此感到困惑,这是我需要做的这个应用程序的最后一件事!

标签: javascriptreactjsherokumern

解决方案


我不知道这是否是最佳做法,但我根本找不到解决此问题的另一种方法。

我添加了

window.location.reload();

到 register.jsx 和 login.jsx axios 请求。我知道这会强制重新加载文档,但这只是我可以让它工作的唯一方法,经过 5 天的尝试解决这个问题,我可以接受。如果有人知道不同的方式,我全神贯注。


推荐阅读