【发布时间】:2018-03-15 20:58:06
【问题描述】:
我在我的应用程序中使用带有 thunk 的反应路由器 v4 进行路由。
我想防止将<AccountPage /> 组件呈现给未登录的用户。我在服务器上发送带有id 和令牌的获取请求以签入数据库,用户是否拥有此令牌。如果有 - 渲染<AccountPage />,如果没有 - 重定向主页。
我不明白什么是实现“条件路由”的好方法,但我发现了一些似乎几乎完全适合我的任务的东西。
https://gist.github.com/kud/6b722de9238496663031dbacd0412e9d
但问题是 <RouterIf /> 中的 condition 始终未定义,因为 fetch 是异步的。我处理这个异步的尝试没有任何结果或错误:
Objects are not valid as a React child (found: [object Promise]) ...
或
RouteIf(...): Nothing was returned from render. ...
代码如下:
//RootComponent
<BrowserRouter>
<Switch>
<Route exact path='/' component={HomePage}/>
<Route path='/terms' component={TermsAndConditionsPage}/>
<Route path='/transaction(\d{13}?)' component={TransactionPage}/>
<RouteIf
condition={( () => {
if( store.getState().userReducer.id, store.getState().userReducer.token) {
// Here i sending id and token on server
// to check in database do user with this id
// has this token
fetch(CHECK_TOKEN_API_URL, {
method: 'post',
headers: {'Accept': 'application/json', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: store.getState().userReducer.id,
token: store.getState().userReducer.token
})
})
.then res => {
// If true – <RouteIf /> will render <AccountPage />,
// else - <Redirect to="/">
// But <RouteIf /> mounts without await of this return
// You can see RouteIf file below
if(res.ok) return true
else return false
})
}
})()}
privateRoute={true}
path="/account"
component={AccountPage}
/>
</Switch>
</BrowserRouter>
//RouteIf.js
const RouteIf = ({ condition, privateRoute, path, component }) => {
// The problem is that condition is
// always undefined, because of fetch's asyncronosly
// How to make it wait untill
// <RouteIf condition={...} /> return result?
return condition
? (<PrivateRoute path={path} component={component} />)
:(<Redirect to="/" />)
}
export default RouteIf
如何让condition 等到fetch 返回答案?或者也许还有另一种更好的方法来检查用户是否登录?
【问题讨论】:
-
返回你的承诺,然后
await或在RouteIf中链接.then?
标签: reactjs authentication asynchronous routing fetch