在盖茨比以编程方式限制路线

Mat*_*att 2 reactjs react-router gatsby

在盖茨比,我将如何以编程方式限制路线?使用反应路由器,我看有可能做一个<Redirect><Route>,但如何将这个在盖茨比实施?做这样的事情...

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

我将把这个文件放在盖茨比的哪里?我会把它放在src/pages其他地方吗?


编辑,要求进一步澄清...

我可以根据@Nenu和Gatsby文档的建议进行这项工作。该文档给出了一个非异步示例,因此我必须对其进行调整以与这样的远程服务器进行交互...

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

另外,我可以<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>
  )
}
Run Code Online (Sandbox Code Playgroud)

...虽然确实是<Redirect to={{ pathname:/ app / profile }} />,但我注意到在重定向之前的瞬间,表单字段为空,只有在此之后,我才重定向到/app/profile(from /app/login)。另外,如果我输入了错误的密码,则会重新呈现我的整个表单(再次重新呈现<View />)。这将是糟糕的用户体验,因为他们将不得不从头开始重新输入所有信息,而且我将无法为无效输入添加样式,等等。我想知道是否有更好的方法用盖茨比做到这一点。

或者,我是否必须从头开始构建表单功能(即,更直接地使用Redux,Router等),而不是依赖于Gatsby的更高抽象水平?

Nen*_*enu 6

Gatsby在后台使用react-router,因此您可以使用它定义仅客户端的路由。

像gatsby一样,在github repo中有一个很好的例子:

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

和有关它的文档:

https://www.gatsbyjs.org/docs/building-apps-with-gatsby/#client-only-routes--用户身份验证

综上所述,这是完成的操作:

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} />
      )
    }
  />
);
Run Code Online (Sandbox Code Playgroud)

2)在所需的前缀“仅客户端”路径中定义路由

假设您想限制对网站的/ app /:path部分的访问,然后限制在/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>
);
Run Code Online (Sandbox Code Playgroud)

这些路由仅存在于客户端上,不会与应用程序的内置资源中的index.html文件相对应。如果您希望人们直接访问客户端路由,则需要设置服务器以正确处理这些路由。(来源

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)
  }
}
Run Code Online (Sandbox Code Playgroud)