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

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

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

const router = createBrowserRouter([
{
path: "/",
element: <RootLayout />,
errorElement: <ErrorPage />,
children: [
  { path: "/", element: <HomePage /> },
  { path: "/home", element: <HomePage /> },
  { path: "/help", element: <HelpPage /> },
  { path: "/signup", element: <SignupPage /> },
  { path: "/signin", element: <SigninPage /> },
  { path: "/resetpwform", element: <ResetPasswordFormPage /> },
  { path: "/emailSent", element: <EmailSentPage /> },
  { path: "/setnewpassword", element: <SetPasswordPage /> },
  { path: "/resetsuccessful", element: <SuccessfulResetPage /> },
  { path: "/editprofile", element: <EditPage />, loader: checkAuthLoader },
  {
    path: "/myreputation",
    element: <ReputationPage />,
    loader: getReputationLoader,
  },
  {
    path: "/makeclassification",
    element: <MakeClassificationPage />,
    loader: checkAuthLoader,
  },
  {
    path: "/codeanalysis",
    element: <CodeSnippetAnalysisPage />,
    loader: checkAuthLoader,
  },
  {
    path: " /myclassifications",
    element: <MyClassificationsPage />,
    loader: checkAuthLoader,
  },
  { path: "/overview", element: <OverviewPage /> },
  { path: "/error", element: <ErrorPage /> },
  { path: "/unauthorized", element: <UnauthorizedPage /> },
  { path: "/tests", element: <Tests /> },
],
},
]);

function App() {
  const [isDarkTheme, setDarkTheme] = useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const token = getAuthToken();
  const tokenDuration = getTokenDuration();
  useEffect(() => {
     if (token) {
     setIsLoggedIn(true);
  setTimeout(() => {
    localStorage.removeItem("token");
    localStorage.removeItem("tokenExpirationDate");
    setIsLoggedIn(false);
  }, tokenDuration); //7 days token duration before expires - 604800000 in ms
}
}, [token, tokenDuration]);

 const themeHandler = () => {
   setDarkTheme((prev) => !prev);
   };

 const handleLogin = () => {
setIsLoggedIn(true);
};

   const handleLogout = () => {
   setIsLoggedIn(false);
 };

 const theme = isDarkTheme ? darkTheme : lightTheme;

return (
   <StyledEngineProvider injectFirst>
  <DarkThemeContext.Provider
    value={{
      handler: themeHandler,
    }}
  >
    <AuthenticationStatusContext.Provider
      value={{
        isLoggedIn: isLoggedIn,
        loginHandler: handleLogin,
        logoutHandler: handleLogout,
      }}
    >
      <ThemeProvider theme={theme}>
        <GlobalStyles></GlobalStyles>
        <RouterProvider router={router} />
      </ThemeProvider>
    </AuthenticationStatusContext.Provider>
  </DarkThemeContext.Provider>
</StyledEngineProvider>
 );
}

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

const ReputationPage = () => {
 const reputationData = useLoaderData();
 //console.log(reputationData);
 return (
<Fragment>
  <ReputationTable data={reputationData}></ReputationTable>
</Fragment>
 );
};

export async function getReputationLoader() {
//checkAuthLoader();
 const token = localStorage.getItem("token");
 const decodedToken = jwt_decode(token);
 const userId = decodedToken.unique_name;

 try {
   const response = await fetch(
  `https://localhost:7182/api/v1/users/reputation/${userId}`,
  {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Bearer " + token,
    },
  }
);
console.log("AQUI 1");
if (!response.ok) {
  //throw new Error();
  return;
} else if (response.ok) {
  const responseInfo = await response.json();
  return responseInfo;
 }
  } catch (error) {
  redirect("/error");
  }
 }

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

643ylb08

643ylb081#

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

// ReputationPage component
const ReputationPage = () => {
    const [reputationData, setReputationData] = useState(null);

    return (
        <Fragment>
            {reputationData !== null ? (
                <ReputationTable data={reputationData}></ReputationTable>
            ) : (
                <div>Loading...</div>
            )}
        </Fragment>
    );
};

// getReputationLoader function
export async function getReputationLoader() {
    const token = localStorage.getItem("token");
    const decodedToken = jwt_decode(token);
    const userId = decodedToken.unique_name;

    try {
        const response = await fetch(
            `https://localhost:7182/api/v1/users/reputation/${userId}`,
            {
                method: "GET",
                headers: {
                    "Content-Type": "application/json",
                    Authorization: "Bearer " + token,
                },
            }
        );

        if (!response.ok) {
            throw new Error("Failed to fetch reputation data");
        }

        const responseInfo = await response.json();
        return responseInfo;
    } catch (error) {
        console.error(error);
        return null;
    }
}

// Usage of useLoaderData in ReputationPage component
const ReputationPage = () => {
    const reputationData = useLoaderData(getReputationLoader);

    return (
        <Fragment>
            {reputationData !== null ? (
                <ReputationTable data={reputationData}></ReputationTable>
            ) : (
                <div>Loading...</div>
            )}
        </Fragment>
    );
};

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

相关问题