繁体   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