Реагировать на роутер с разными шаблонами для разных маршрутов v.5

Jan 18 2021

Привет, я видел этот вопрос, и это именно то, что я ищу, но я не могу заставить его работать. Маршрутизаторы React Router V4 с мастер-страницами / шаблонами

Я использую версию 5.2

Компонент приложения включает в себя навигацию и обертывает два пути с двумя компонентами шаблона, «Общедоступный» и «Частный», и когда я нажимаю каждую ссылку, я ожидаю, что эта страница будет обернута этим шаблоном, но вместо этого работает только первая ссылка и показывает шаблон. Вторая ссылка изменяет только URL-адрес в адресной строке браузера, и на странице остается только содержимое первого шаблона, а содержимое второй страницы не отображается. Если я изменяю порядок ссылок, всегда только верхняя ссылка получает правильный шаблон.

Здесь я определяю маршруты и ссылки на них.

class App extends Component {
  render() {
    return (
      <Router>
        <div>
          <ul><li><Link to="/">Home</Link></li>
            <li><Link to="/members">Members</Link></li>
          </ul>
        </div>
        <Switch>
          <Public>
            <Route exact path="/"><Home /></Route>
          </Public>
          <Private>
            <Route path="/members"><Members /></Route>
          </Private>
        </Switch>
      </Router>
    );
  }
}
export default App;

Мои частные и общедоступные шаблоны одинаковы, за исключением заголовков, в одном из которых указано личное, а в другом - общедоступное.

class Private extends Component {
  render() {
    return (
      <div className="container">
        <div className="row">
          <div className="col-md-2"><h2>PRIVATE</h2></div>
          <div className="col-md-8">{this.props.children}</div>
          <div className="col-md-2"></div>
        </div>
      </div>
    );
  }
}

export default Private;

Некоторое время я искал что-то подобное, так как это выглядит как потенциально интересное решение. Если кто-нибудь знает, как это исправить, я был бы очень признателен. Спасибо

Ответы

1 TaghiKhavari Jan 18 2021 at 18:15

Вот что Switchделает компонент:

          React.Children.forEach(this.props.children, child => {
            if (match == null && React.isValidElement(child)) {
              element = child;

              const path = child.props.path || child.props.from;

              match = path
                ? matchPath(location.pathname, { ...child.props, path })
                : context.match;
            }
          });

как вы видите, Switchкомпонент заботится только о первом уровне своих дочерних элементов и ищет в нем вызываемую опору path or from. если он не найдет, он предполагает, что все pathсовпадут. поэтому он всегда показывает первых детей, несмотря ни на что.

вам нужно изменить порядок детей следующим образом:

<Switch>
  <Route exact path="/">
    <Public>
      <Home />
    </Public>
  </Route>
  <Route path="/members">
    <Private>
      <Members />
    </Private>
  </Route>
</Switch>