Ограничить маршруты программно в Гэтсби - PullRequest
0 голосов
/ 25 мая 2018

В Гэтсби, как бы я ограничил маршруты программно?Используя реагирующий маршрутизатор , я вижу, что можно сделать <Redirect> с <Route>, но как это будет реализовано в Гэтсби?Чтобы сделать что-то вроде этого ...

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

Где бы я положил этот файл в Гэтсби?Могу ли я поставить его в src/pages или в другом месте?


Отредактировано, с просьбой дать дополнительные разъяснения ...

Я могу получить эту работу по совету @Nenu иГэтсби документы.Документы привели не асинхронный пример, поэтому мне пришлось настроить его для взаимодействия с удаленным сервером, как этот ...

async handleSubmit(event) {
  event.preventDefault()
  await handleLogin(this.state)
    .then(response => _this.setState({isLoggedIn: isLoggedIn()}))
    .catch(err => { console.log(err) });
}

Кроме того, я могу использовать <PrivateRoute /> с этим.

К сожалению, хотя, когда я рендеринг использую ...

render() {
  if (isLoggedIn()) {
    return <Redirect to={{ pathname: `/app/profile` }} />
  }

  return (
    <View title="Log In">
      <Form
        handleUpdate={e => this.handleUpdate(e)}
        handleSubmit={e => this.handleSubmit(e)}
      />
    </View>
  )
}

... в то время как я действительно <Redirect to={{ pathname: / app / profile }} />, я замечаю, что за долю секунды доЯ перенаправляю, поля формы очищаются, и только после этого я перенаправляюсь на /app/profile/app/login).Кроме того, если я введу неверный пароль, вся моя форма будет перерисована (повторная отрисовка <View /> снова).Это было бы плохо для пользователя, потому что им пришлось бы заново вводить всю свою информацию с нуля, плюс я бы не смог добавить стили для недопустимых вводов и т. Д. Мне интересно, есть ли лучший способчтобы сделать это с Гэтсби.

Или мне нужно было бы создавать функциональность формы с нуля (то есть, используя Redux, Router и т. д. более напрямую), а не зависеть от более высокого уровня абстракции Гэтсби?

1 Ответ

0 голосов
/ 28 мая 2018

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

Как и в случае с Гэтсби, как всегда, очень хороший примерgithub repo:

https://github.com/gatsbyjs/gatsby/tree/master/examples/simple-auth

И документ об этом:

https://www.gatsbyjs.org/docs/building-apps-with-gatsby/#client-only-routes--user-authentication

Подводя итог, вот что сделано:

1) Создайте PrivateRoute компонент в / src / components

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      !isLoggedIn() ? (
        // If we’re not logged in, redirect to the login page.
        <Redirect to={{ pathname: `/app/login` }} />
      ) : (
        <Component {...props} />
      )
    }
  />
);

2) Определите маршруты в нужном префиксе «путь только для клиента»

Предположим, вы хотите ограничить доступ к разделу / app /: путь вашего сайта, затем в / src / pages / app.js :

const App = () => (
  <div>
    <PrivateRoute path="/app/profile" component={Home} />
    <PrivateRoute path="/app/details" component={Details} />
    <Route path="/app/login" component={Login} />
  </div>
);

Эти маршруты будут существовать только на клиенте и не будут соответствовать файлам index.html в встроенных ресурсах приложения.Если вы хотите, чтобы люди посещали клиентские маршруты напрямую, вам необходимо настроить сервер для правильной обработки этих маршрутов.( source )

3) Белый список клиентских маршрутов в gatsby-node.js

exports.onCreatePage = async ({ page, boundActionCreators }) => {
  const { createPage } = boundActionCreators

  // page.matchPath is a special key that's used for matching pages
  // only on the client.
  if (page.path.match(/^\/app/)) {
    page.matchPath = `/app/:path`

    // Update the page.
    createPage(page)
  }
}
...