簡體   English   中英

防止 React Router 在不導航的情況下直接訪問 URL

[英]Prevent React Router from accessing directly an URL without navigating

我正在嘗試創建一個由不同頁面(開始菜單、加載屏幕等)組成的小游戲界面。
當然,我不希望用戶僅通過更改地址欄中的 URL 就能夠在這些頁面之間導航。 有沒有辦法忽略/拒絕來自地址欄的用戶輸入,而只是從代碼中導航頁面?

非常感謝您提前! :)

我能夠通過以下步驟做到這一點:

  • 創建一個存儲lastVisitedLocation的上下文,當用戶點擊鏈接時會編輯該值。 (我們可以從應用程序的任何地方更新它!)
  • 上下文還公開了一個可以更改先前值的registerLocation函數。
const LocationContext = React.createContext(null);

function LocationContextProvider({ children }) {
  const lastVisitedLocation = React.useRef(null);
  function registerLocation(location) {
    lastVisitedLocation.current = location;
  }
  return (
    <LocationContext.Provider value={{ registerLocation, lastVisitedLocation }}>
      {children}
    </LocationContext.Provider>
  );
}
  • 包裝來自react-router-domLink ,並在我們點擊鏈接時更改lastVisitedLocation
const MySpecialLink = React.forwardRef((props, ref) => {
  const { registerLocation } = React.useContext(LocationContext);
  return (
    <Link onClick={() => registerLocation(props.to)} ref={ref} {...props} />
  );
});

  • 創建一個鈎子來驗證用戶之前是否在應用中導航過,並且我們不在允許的路線中。 如果我們檢測到通過 URL 的直接訪問,則拋出錯誤(我們基本上可以實現任何所需的行為)。
const PUBLIC_ALLOWED_ROUTES = ["/home", "/"];

function useInvalidUrlAccess() {
  const currentLocation = useLocation();
  const { lastVisitedLocation } = React.useContext(LocationContext);
  if (
    lastVisitedLocation.current === null &&
    !PUBLIC_ALLOWED_ROUTES.includes(currentLocation.pathname)
  ) {
    throw new Error("Cannot come here directly, buddy");
  }
}
  • 將您的Switch包裹在LocationContextProvider
    <LocationContextProvider>
      <MySpecialLink to="/">Home</MySpecialLink>
      <br />
      <MySpecialLink to="/page1">Page 1</MySpecialLink>
      <br />
      <MySpecialLink to="/page2">Page 2</MySpecialLink>
      <br />
      <Switch>
        <Route exact path="/">
          <HomePage />
        </Route>
        <Route exact path="/home">
          <HomePage />
        </Route>
        <Route exact path="/page1">
          <Page1 />
        </Route>
        <Route exact path="/page2">
          <Page2 />
        </Route>
        <Route component={NotFound} />
      </Switch>
    </LocationContextProvider>
  • 通過調用函數頂層的鈎子來保護你的組件

function HomePage() {
  useInvalidUrlRoutes();
  return "This is the content of HOME the page";
}
function Page1() {
  useInvalidUrlRoutes();
  return "This is the content of the page 1";
}
function Page2() {
  useInvalidUrlRoutes();
  return "This is the content of the page 2";
}
function NotFound() {
  return "You hit the wrong road, buddy!";
}

最后,這是一個有效的代碼和盒子演示 例如,我使用throw new Error將路由直接標記為不可導航,但基本上你可以做任何事情。

您無法阻止瀏覽器打開 URL 欄中輸入的 URL。

您可以在應用程序狀態中有一個標志,顯示當前會話是否從主頁啟動,並僅在主頁組件上將其設置為true 然后,您可以向要限制訪問的頁面組件添加以下條件:如果標志為true ,則可能會打開該頁面,否則重定向到主頁。

請注意,由於實施的限制,無法重新加載訪問受限的頁面。

PS:這是一個非常令人困惑的要求,它打破了網絡的工作方式。 這是什么原因?

您可以將所有網址重定向到您的主頁。

import {
    Redirect
} from "react-router-dom";

     <Redirect from={`${match.url}/`} to={`${match.url}/mainpage`} />

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM