Вложенные маршруты и не найденный маршрут в реактивном маршрутизаторе dom v5 - PullRequest
1 голос
/ 20 июня 2020

Пытаясь создать вложенные маршруты в реактивном маршрутизаторе dom v5, я нашел этот ответ , который объясняет, как это сделать очень хорошо

(пожалуйста, взгляните на код здесь потому что это немного отличается от ответа, упомянутого выше)

Макеты. js

const NotFound = () => <h1>Not Found</h1>;

function Layouts() {
  return (
    <Switch>
      <Route path="/auth" component={AuthLayout} />
      <Route path="/app" component={AppLayout} />
      <Route path="/" component={NotFound} />
    </Switch>
  );
}

AuthLayout

const Signup = () => <p>Login</p>;
const Login = () => <p>Sign up</p>;

function AuthLayout() {
  return (
    <div>
      <h1>Auth Layout</h1>
      <Route path="/auth/signup" exact component={Signup} />
      <Route path="/auth/login" exact component={Login} />
      {/* Commenting this because I want to go to NotFound component */}
      {/* <Redirect from="/auth" to="/auth/login" exact /> */}
    </div>
  );
}

AppLayout

const Home = () => <p>Home</p>;
const Dashboard = () => <p>Dashboard</p>;

function AppLayout() {
  return (
    <div>
      <h1>App Layout</h1>
      <Route path="/app/home" exact component={Home} />
      <Route path="/app/dashboard" exact component={Dashboard} />
      {/* Commenting this because I want to go to NotFound component */}
      {/* Redirect from="/app" to="/app/home" exact /> */}
    </div>
  );
}

Но у этого есть одна проблема: если вы go перейдете к маршруту с /app/somethingnotfound, он не будет go до <Route path="/" component={NotFound} />, он останется внутри AppLayout и не отобразит маршрут.

Как я могу преобразовать /app/somethingnotfound go в <Route path="/" component={NotFound} /> в этом случае?

Изменить:

Для большей ясности: я не хочу просто добавьте <Route component={NotFound} /> внутри AuthLayout и AppLayout, потому что он будет отображать другие вещи. Что мне действительно нужно, так это показать верхний уровень NotFound.

Ответы [ 3 ]

1 голос
/ 20 июня 2020

Не найденный компонент обычно работает так:

<Router>
  <Switch>
    <Route exact path="/auth" component={AuthLayout} />
    <Route exact path="/app" component={AppLayout} />
    <Route component={NotFound} />
  </Switch>
</Router>

Но вы не можете пометить /auth и /app как exact, поскольку они содержат вложенные маршруты. Итак, вы должны сделать:

<Router>
  <Switch>
    <Route path="/auth" component={AuthLayout} />
    <Route path="/app" component={AppLayout} />
    <Route exact path="/404" component={NotFound} />
    <Redirect to='/404' />
  </Switch>
</Router>

и ваш компонент (например, AppLayout) с вложенными маршрутами:

<>
<h1>App Layout</h1>
<Switch>
  <Route path="/app/home" exact component={Home} />
  <Route path="/app/dashboard" exact component={Dashboard} />
  <Redirect to="/404" />
</Switch>
</>
0 голосов
/ 20 июня 2020

<Route path="/" component={NotFound} /> не соответствует всем вложенным, которые не реализованы, потому что Switch в компоненте Layouts будет отображать только первый Route дочерний элемент, который соответствует pathname. В вашем случае он соответствует маршруту с компонентом AppLayout, когда вы go путь /app/somethingdoesntexist, поэтому он отображает только компонент AppLayout.

Решение

Лучше реализовать маршрут NotFound для каждого макета, используя вложенные Switch компоненты, например

function AppLayout() {
  const { path, url } = useRouteMatch();

  return (
      <Switch>
        <Route path={`${path}/home`} exact component={Home} />
        <Route path={`${path}/dashboard`} exact component={Dashboard} />
        <Route path="*" component={NotFound} />
      </Switch>
  );
}

В приведенном выше случае мы получили согласованный путь с помощью хука useRouteMatch и вложить еще один компонент Switch, который будет отображать любой вложенный маршрут, который соответствует path, и мы предоставляем запасной вариант Route с указанием пути как "*", который будет отображать компонент NotFound, когда совпадение не найдено.

Вот полный пример решения codeandbox .

Вы также можете увидеть пример вложения указано в документации.

0 голосов
/ 20 июня 2020
• 1000 другие маршруты.
const NotFound = () => <div className="not_found"><h1>Not Found</h1></div>;

const RouteNotFound = () => <Redirect to={{ state: { notFoundError: true } }} />;

const CaptureRouteNotFound = withRouter(({children, location}) => {
  return location && location.state && location.state.notFoundError ? <NotFound /> : children;
});

const Settings = () => {
  return (
    <Switch>
      <Route path="/settings/account" render={() => <h1>Account Settings</h1>} />
      <Route path="/settings/profile" render={() => <h1>Profile Settings</h1>} />

      <RouteNotFound />
    </Switch>
  );
};

const AppShell = ({children}) => {
  return (
    <div className="application">
      <header>Application</header>
      {children}
    </div>
  );
};

const Application = () => {
  return (
    <Router>
      <CaptureRouteNotFound>
        <AppShell>
          <Switch>
            <Route path="/settings" render={() => <Settings />} />
            <Route path="/profile" render={() => <h1>User Profile</h1>} />

            <RouteNotFound />
          </Switch>
        </AppShell>
      </CaptureRouteNotFound>
    </Router>
  );
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...