React Router 4 Нет совпадений с вложенными маршрутами

Я хотел бы иметь глобальный маршрут No Match для обработки всех сообщений 404 . После входа в систему все основные представления попадают в макет, заключенный в верхний и нижний колонтитулы. Хотя компонент NotFound должен отображаться за пределами этого макета.

Вот ссылка на "рабочий" образец кода

Вот упрощенный пример кода:

const App = () => (
  <Switch>
    <Route path="/register" component={Register} />
    <Route path="/signin" component={SignIn} />
    <Route path="/" component={Home} />
    <Route component={NotFound} />
  </Switch>
);

const Home = () => (
  <div>
    <Header />
    <main>
      <Switch>
        <Route exact path="/" component={Main} />
        <Route path="/list" component={List} />
        <Route path="/tasks" component={Tasks} />
      </Switch>
    </main>
    <Footer />
  </div>
);

Приведенный выше образец кода работает для рендеринга макета по своему усмотрению, но отображает пустой макет по несовпадающим URL-адресам. Если я установлю корневой путь приложения на exact, я могу получить NotFound, но потеряю домашние маршруты

Несмотря на вариации использования / неиспользования exact на корнях, перемещая корни в конец списка Routes, я могу заставить части ожидаемого поведения работать, но не все это работает согласованно.

Если я захожу в "/", я ожидаю увидеть:

Some Header Thing
Home
Some Footer Thing

Если я захожу в "/ list", я ожидаю увидеть:

Some Header Thing
List
Some Footer Thing

Если я захожу в "/ register", я ожидаю увидеть:

Register

Если я захожу в "/ foobar", я ожидаю увидеть:

Not Found

person Jadam    schedule 21.10.2017    source источник


Ответы (1)


Это ниже заставит маршруты работать с относительно небольшими изменениями в вашем коде, и, поскольку я не хочу слишком много предполагать, я не решаюсь сильно реструктурировать вещи. Но, как вы можете видеть, это приводит к использованию компонента «Главная» для перехода ко всем разделам с верхними и нижними колонтитулами, а «Не найдено» улавливает остальные. Тем не менее, он сильно сглаживает вещи, которые могут стать громоздкими при большом количестве маршрутов.

const App = () => (
  <BrowserRouter>
    <Switch>
      <Route path="/register" render={() => <div>Register</div>} />
      <Route path="/signin" render={() => <div>Sign in</div>} />
      <Route path="/list" component={Home} />
      <Route path="/tasks" component={Home} />
      <Route exact path="/" component={Home} />
      <Route render={() => <div>Not Found</div>} />
    </Switch>
  </BrowserRouter>
);

const Home = () => (
  <div>
    <header>Some Header Thing</header>
    <main>
      <Switch>
        <Route path="/list" render={() => <div>List</div>} />
        <Route path="/tasks" render={() => <div>Tasks</div>} />
        <Route path="/" render={() => <div>Home</div>} />
      </Switch>
    </main>
    <footer>Some Footer Thing</footer>
  </div>
);

(Кроме того, я только что понял, что использовал образец кода Sandbox, который вы дали в качестве модели, а не ваши Qs - извините за это.)


Другой способ подумать о структуре - это немного более буквально следовать вашему очень прямому и хорошему описанию. Вы пишете, что сначала должен быть зарегистрированный и вошедший в систему пользователь, затем должны появиться различные маршруты сайта, после этого верно. Вместо того, чтобы думать об этом как о вопросе маршрутизации, подумайте об этом как о props вопросе - есть ли определенные user реквизиты? Вы можете использовать троицу для проверки существования пользователя в App, например:

const App = ({user}) => (
  <div>
    { user ? Home : Signin }
  </div>
)

где Home отобразит вашу версию существующего компонента, а Signin перенесет вас в компонент, аналогичный компоненту App. Вы также можете оставить маршрут «Не найдено» в App.

person andrewatkinson    schedule 21.10.2017
comment
Да, я полагаю, что это работает, хотя, как вы предположили, похоже, что я повторно реализую старую конфигурацию маршрутизатора v3. Такое ощущение, что что-то вроде этого не должно быть таким сложным, поэтому очень вероятно, что я не полностью разбираюсь в API v4. Я буду продолжать ковыряться и учту ваши предложения. - person Jadam; 22.10.2017