Как добиться условной маршрутизации на основе параметра в запрашиваемом маршруте? - PullRequest
1 голос
/ 20 января 2020

Я занимаюсь разработкой блога, похожего на блог React js, и нахожу некоторые проблемы с управлением маршрутами. Мои страницы с URL-адресами статей выглядят так: веб-сайт / pages / 3

Я бы хотел перенаправить на домашнюю страницу, когда индекс страницы равен 1, поскольку домашняя страница по умолчанию является первой страницей со статьями. Мой маршрутизатор выглядит так:

<Router>
        <Switch>
          <Route exact path="/" render={() => <Page postsPerPage={3}/>} />
          <Route exact path="/Page/:activePage" render={() => <Page postsPerPage={3}/>} />
          <Route path="/Login" component={Login} />
          <PrivateRoute path="/AddPost" component={AddPost}  />
          <Route path="/:postLocation" component={Post}  />
        </Switch>
      </Router>

Я хотел бы направить "/ Page /: activePage" к компоненту, который отображает маршрут "/", если activePage равен 1. Таким образом, компонент будет таким же ( Страницы), но путь будет другим.

Может ли условный рендеринг в маршрутизаторе добиться цели, и если да, то как? Я думал о чем-то вроде этого:

 <Route exact path="/Page/:activePage" render={() => 
         {
            let {activePage} = useParams()
            if (activePage == 1) return (<Redirect to="/"/>)
            else return(<Page  postsPerPage={3}/>) 
          } 
          }/>

Однако кажется, что React недоволен тем, что я использую там useParams (есть ошибка компиляции: React Hook "useParams" нельзя вызвать внутри обратного вызова. React Hooks должен быть вызван в компоненте функции React или в пользовательской функции React Hook-реакции-hooks / rules-of-hooks)

Я тестировал этот фрагмент с постоянным значением 1 вместо параметра activePage, и он действительно перенаправлял так это в основном оставляет меня с вопросом о том, как я могу получить параметр из пути?

Ответы [ 3 ]

1 голос
/ 20 января 2020

Вы, вероятно, должны обрабатывать маршрутизацию внутри компонента Pages или, если хотите, создать отдельный компонент для обработки условной маршрутизации.

, например:

function Pages (props) {

    const {activePage} = useParams()

    return activePage === 1 ? <Redirect to='/' /> : (
<div>
Your Pages component content here
</div>

)
}

export default Pages;

или

function ConditionalRoutingComponent(props) {

    const {activePage} = useParams()

    return activePage === 1 ? <Redirect to='/' /> : <Page  postsPerPage={3}/>
}

export default ConditionalRoutingComponent;

Надеюсь, это поможет

1 голос
/ 20 января 2020

Функция рендеринга Компонента a вызывается с тремя параметрами: совпадением, историей и местоположением. Вы можете использовать их, чтобы выполнить действие, которое вы пытаетесь сделать с крючками.

<Route ... render={({match}) => {
 if (match.params.activePage == 1) {
  doYourStuff()
 }
}}
0 голосов
/ 20 января 2020

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

 <Route exact path="/Page/:activePage" render={(props) => 
         {
            if (props.match.params.activePage == 1) return (<Redirect to="/"/>)
            else return(<Page  postsPerPage={3}/>) 
          } 
      }
/>

Рассматривая приведенный выше пример, я не буду ничего перенаправлять, но перенесу логический c в компонент Page. внутри функции componentDidMount или useEffect, которая извлекает параметр activePage. Я проверю, равно ли это 1 (или какому-либо дополнительному значению, которое вы выберете для использования). Затем я выполняю логи c, которые будут выполнены домашним компонентом, в противном случае я обычно продолжаю маршрут. Например, если вы извлекли его и извлекли его в бэкэнд для случая, когда его, а не 1, то когда он равен 1, вы можете просто вернуться из функции, и она будет работать так, как если бы она находилась на домашней странице. в качестве альтернативы, после проверки, если это 1, вы можете затем перенаправить обратно к '/'.

...