在Gatsby中,我如何以编程方式限制路线?使用react-router,我发现可以使用<Redirect>
进行<Route>
,但如何在Gatsby中实施?要做这样的事......
<Route exact path="/" render={() => (
loggedIn ? (
<Redirect to="/dashboard"/>
) : (
<PublicHomePage/>
)
)}/>
我将这个文件放在Gatsby中?我会把它放在src/pages
或其他地方吗?
编辑,要求进一步澄清......
根据@Nenu和Gatsby文档的建议,我能够完成这项工作。文档给出了一个非异步的例子,所以我不得不调整它以便与这样的远程服务器进行交互......
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等),而不是依赖于Gatsby的更高抽象级别?
答案 0 :(得分:5)
Gatsby使用 react-router ,因此您可以使用它定义仅限客户的路线。
与gatsby一样,在github回购中有一个非常好的例子:
https://github.com/gatsbyjs/gatsby/tree/master/examples/simple-auth
关于它的文档:
https://www.gatsbyjs.org/docs/building-apps-with-gatsby/#client-only-routes--user-authentication
总结一下,这就是做了什么:
PrivateRoute
组件
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} />
)
}
/>
);
假设您要限制访问您网站的 / 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>
);
这些路由仅存在于客户端上,与应用程序构建的资产中的index.html文件不对应。如果您希望人们直接访问客户端路由,则需要设置服务器以正确处理这些路由。 (source)
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)
}
}