javascript React应用在fetch()请求后被破坏

cclgggtu  于 2023-05-12  发布在  Java
关注(0)|答案(1)|浏览(130)

所以我在我的React应用程序中遇到了一个问题,我似乎无法解决,已经两天了。我在App.js文件中定义了路由,并使用了loader方法。其中一个路由(/myreputation)有一个loader方法,它向我的后端服务器执行fetch请求。问题是,每当我刷新页面(在请求发出后),我的应用程序就会被破坏,就好像css被搞乱了一样。这是App.js文件,我在其中定义了加载器方法(getReputationLoader):

  1. const router = createBrowserRouter([
  2. {
  3. path: "/",
  4. element: <RootLayout />,
  5. errorElement: <ErrorPage />,
  6. children: [
  7. { path: "/", element: <HomePage /> },
  8. { path: "/home", element: <HomePage /> },
  9. { path: "/help", element: <HelpPage /> },
  10. { path: "/signup", element: <SignupPage /> },
  11. { path: "/signin", element: <SigninPage /> },
  12. { path: "/resetpwform", element: <ResetPasswordFormPage /> },
  13. { path: "/emailSent", element: <EmailSentPage /> },
  14. { path: "/setnewpassword", element: <SetPasswordPage /> },
  15. { path: "/resetsuccessful", element: <SuccessfulResetPage /> },
  16. { path: "/editprofile", element: <EditPage />, loader: checkAuthLoader },
  17. {
  18. path: "/myreputation",
  19. element: <ReputationPage />,
  20. loader: getReputationLoader,
  21. },
  22. {
  23. path: "/makeclassification",
  24. element: <MakeClassificationPage />,
  25. loader: checkAuthLoader,
  26. },
  27. {
  28. path: "/codeanalysis",
  29. element: <CodeSnippetAnalysisPage />,
  30. loader: checkAuthLoader,
  31. },
  32. {
  33. path: " /myclassifications",
  34. element: <MyClassificationsPage />,
  35. loader: checkAuthLoader,
  36. },
  37. { path: "/overview", element: <OverviewPage /> },
  38. { path: "/error", element: <ErrorPage /> },
  39. { path: "/unauthorized", element: <UnauthorizedPage /> },
  40. { path: "/tests", element: <Tests /> },
  41. ],
  42. },
  43. ]);
  44. function App() {
  45. const [isDarkTheme, setDarkTheme] = useState(false);
  46. const [isLoggedIn, setIsLoggedIn] = useState(false);
  47. const token = getAuthToken();
  48. const tokenDuration = getTokenDuration();
  49. useEffect(() => {
  50. if (token) {
  51. setIsLoggedIn(true);
  52. setTimeout(() => {
  53. localStorage.removeItem("token");
  54. localStorage.removeItem("tokenExpirationDate");
  55. setIsLoggedIn(false);
  56. }, tokenDuration); //7 days token duration before expires - 604800000 in ms
  57. }
  58. }, [token, tokenDuration]);
  59. const themeHandler = () => {
  60. setDarkTheme((prev) => !prev);
  61. };
  62. const handleLogin = () => {
  63. setIsLoggedIn(true);
  64. };
  65. const handleLogout = () => {
  66. setIsLoggedIn(false);
  67. };
  68. const theme = isDarkTheme ? darkTheme : lightTheme;
  69. return (
  70. <StyledEngineProvider injectFirst>
  71. <DarkThemeContext.Provider
  72. value={{
  73. handler: themeHandler,
  74. }}
  75. >
  76. <AuthenticationStatusContext.Provider
  77. value={{
  78. isLoggedIn: isLoggedIn,
  79. loginHandler: handleLogin,
  80. logoutHandler: handleLogout,
  81. }}
  82. >
  83. <ThemeProvider theme={theme}>
  84. <GlobalStyles></GlobalStyles>
  85. <RouterProvider router={router} />
  86. </ThemeProvider>
  87. </AuthenticationStatusContext.Provider>
  88. </DarkThemeContext.Provider>
  89. </StyledEngineProvider>
  90. );
  91. }

这是MyReputation页面,我在其中使用了与loader方法一起使用的数据:

  1. const ReputationPage = () => {
  2. const reputationData = useLoaderData();
  3. //console.log(reputationData);
  4. return (
  5. <Fragment>
  6. <ReputationTable data={reputationData}></ReputationTable>
  7. </Fragment>
  8. );
  9. };
  10. export async function getReputationLoader() {
  11. //checkAuthLoader();
  12. const token = localStorage.getItem("token");
  13. const decodedToken = jwt_decode(token);
  14. const userId = decodedToken.unique_name;
  15. try {
  16. const response = await fetch(
  17. `https://localhost:7182/api/v1/users/reputation/${userId}`,
  18. {
  19. method: "GET",
  20. headers: {
  21. "Content-Type": "application/json",
  22. Authorization: "Bearer " + token,
  23. },
  24. }
  25. );
  26. console.log("AQUI 1");
  27. if (!response.ok) {
  28. //throw new Error();
  29. return;
  30. } else if (response.ok) {
  31. const responseInfo = await response.json();
  32. return responseInfo;
  33. }
  34. } catch (error) {
  35. redirect("/error");
  36. }
  37. }

我觉得应用程序在请求后没有呈现。每当我不使用这个加载器(getReputationLoader)时,一切都工作得很好。我真的找不到解决的办法。谢谢你的时间。

643ylb08

643ylb081#

看起来你面临的问题是因为你的应用处理异步请求的方式。具体来说,当您刷新页面时,应用会重新加载,并且某些操作(如fetch请求)可能在组件再次呈现之前无法完成。
想象一下,你正在加载一个网页,当它还在加载时,你快速刷新页面。在这种情况下,来自fetch请求的数据有可能在组件尝试呈现它之前没有按时到达。结果,应用程序中断,CSS样式看起来一团糟。
若要解决此问题,您需要确保在呈现组件之前完成获取请求。一种方法是按以下方式修改代码:
在ReputationPage组件中,将reputationData的初始状态设置为空。这有助于区分加载状态和数据可用时的状态。
更新getReputationLoader函数以适当地处理错误,并在失败时返回null。
使用ReputationPage组件中的useLoaderData钩子异步加载信誉数据并相应地更新状态。
通过实现这些更改,您可以在等待获取信誉数据时显示加载消息或UI。这可以防止CSS在刷新页面时出现损坏。

  1. // ReputationPage component
  2. const ReputationPage = () => {
  3. const [reputationData, setReputationData] = useState(null);
  4. return (
  5. <Fragment>
  6. {reputationData !== null ? (
  7. <ReputationTable data={reputationData}></ReputationTable>
  8. ) : (
  9. <div>Loading...</div>
  10. )}
  11. </Fragment>
  12. );
  13. };
  14. // getReputationLoader function
  15. export async function getReputationLoader() {
  16. const token = localStorage.getItem("token");
  17. const decodedToken = jwt_decode(token);
  18. const userId = decodedToken.unique_name;
  19. try {
  20. const response = await fetch(
  21. `https://localhost:7182/api/v1/users/reputation/${userId}`,
  22. {
  23. method: "GET",
  24. headers: {
  25. "Content-Type": "application/json",
  26. Authorization: "Bearer " + token,
  27. },
  28. }
  29. );
  30. if (!response.ok) {
  31. throw new Error("Failed to fetch reputation data");
  32. }
  33. const responseInfo = await response.json();
  34. return responseInfo;
  35. } catch (error) {
  36. console.error(error);
  37. return null;
  38. }
  39. }
  40. // Usage of useLoaderData in ReputationPage component
  41. const ReputationPage = () => {
  42. const reputationData = useLoaderData(getReputationLoader);
  43. return (
  44. <Fragment>
  45. {reputationData !== null ? (
  46. <ReputationTable data={reputationData}></ReputationTable>
  47. ) : (
  48. <div>Loading...</div>
  49. )}
  50. </Fragment>
  51. );
  52. };

1.在ReputationPage组件中用默认值(例如,空)初始化reputationData状态。
1.修改getReputationLoader函数以捕获任何错误并适当地处理它们,例如将信誉数据设置为null。
1.在ReputationPage组件中,使用useLoaderData钩子异步加载信誉数据并更新状态。
通过执行这些步骤,将异步获取信誉数据,并且组件将显示加载消息或UI,直到数据可用。这应该可以防止CSS在刷新页面时变得混乱。

展开查看全部

相关问题