【发布时间】:2020-07-08 13:46:39
【问题描述】:
我正在尝试在以下功能组件中使用异步但抛出错误
const RouteConfig = async ({ component: Component, fullLayout, user, auth, ...rest}) => (
<Route
{...rest}
render={props => {
return (
<ContextLayout.Consumer>
{context => {
let LayoutTag =
fullLayout === true
? context.fullLayout
: context.state.activeLayout === 'horizontal'
? context.horizontalLayout
: context.VerticalLayout
const verified = await verifyToken(auth.values)
return (auth.values !== undefined && auth.values.isSignedIn && verified) ? (
<LayoutTag {...props} permission='{user}'>
<Suspense fallback={<Spinner />}>
<Component {...props}></Component>
</Suspense>
</LayoutTag>
) : (
<context.fullLayout {...props} permission={user}>
<Suspense fallback={<Spinner />}>
<Login {...props} />
</Suspense>
</context.fullLayout>
)
}}
</ContextLayout.Consumer>
)
}}
/>
)
const mapStateToProps = state => {
return {
user: state.auth.login.userRole,
auth: state.auth.login
}
}
const AppRoute = connect(mapStateToProps)(RouteConfig)
下面是返回真假的verifyToken函数
const verifyToken = async props => {
if (props.accessToken !== undefined) {
//if (props !== undefined) {
if (assertAlive(jwt.decode(props.accessToken))) {
const verified = await refreshToken(props)
console.log(verified)
if (verified){
console.log('Authorized')
return true
} else {
console.log('Unauthorized')
return false
}
} else {
return false
}
}else
return false
}
function assertAlive (decoded) {
const now = Date.now().valueOf() / 1000
if (typeof decoded.exp !== 'undefined' && decoded.exp < now) {
//throw new Error(`token expired: ${JSON.stringify(decoded)}`)
return false
}
if (typeof decoded.nbf !== 'undefined' && decoded.nbf > now) {
//throw new Error(`token not yet valid: ${JSON.stringify(decoded)}`)
return false
}
return true
}
上面使用的 refreshToken 有一个从 API 调用中获取响应的函数
export const refreshToken = async () => {
const options = { withCredentials: true };
const resp = await axios.post('http://localhost:4000/api/auth/verifyToken',{}, options).catch(err => {console.log(err); return false;});
//console.log(resp.status)
if (resp.status === 200){
//console.log('200 passed')
return true
}else if (resp.status === 401){
//console.log('401 failed')
return false
}else{
//console.log('204 failed')
return false
}
}
如果有任何建议可以解决此问题,我们将不胜感激。如果有人有更好的编码方法,请告诉我。我对 ReactJS 有点陌生,并愿意接受建议。 FIrst 函数用于检查每个路由是否 Token 被授权。如果它被授权它允许访问页面,如果没有重定向到登录页面。
根据@Mordechai 的建议,我进行了以下更改,但会引发错误
./src/Router.js 第 193:40 行:React Hook "useState" 在函数 "verified" 中被调用,该函数既不是 React 函数组件也不是自定义 React Hook 函数 react-hooks/rules-of-hooks 第 194:3 行:React Hook "useEffect" 在函数 "verified" 中被调用,该函数既不是 React 函数组件也不是自定义 React Hook 函数 react-hooks/rules-of-hooks
function verified(auth){
const [verified, setVerifiedValue] = useState(verifyToken(auth.values));
useEffect(() => { setVerifiedValue(verifyToken(auth.values) )})
return verified;
}
const RouteConfig = ({ component: Component, fullLayout, user, auth, ...rest}) => (
<Route
{...rest}
render={props => {
//useEffect(() => {const verified = verifyToken(auth.values) });
return (
<ContextLayout.Consumer>
{context => {
let LayoutTag =
fullLayout === true
? context.fullLayout
: context.state.activeLayout === 'horizontal'
? context.horizontalLayout
: context.VerticalLayout
console.log(VerifiedToken)
return (auth.values !== undefined && auth.values.isSignedIn && VerifiedToken) ? (
<LayoutTag {...props} permission='{user}'>
<Suspense fallback={<Spinner />}>
<Component {...props}></Component>
</Suspense>
</LayoutTag>
) : (
<context.fullLayout {...props} permission={user}>
<Suspense fallback={<Spinner />}>
<Login {...props} />
</Suspense>
</context.fullLayout>
)
}}
</ContextLayout.Consumer>
)
}}
/>
)
const mapStateToProps = state => {
return {
user: state.auth.login.userRole,
auth: state.auth.login
}
}
const AppRoute = connect(mapStateToProps)(RouteConfig)
const VerifiedToken = connect(mapStateToProps)(verified)
【问题讨论】:
-
简单的答案:你不能。函数式组件不能是异步函数
-
在
useEffect钩子里做你所有的异步逻辑 -
我尝试使用 use Effect 但不确定在组件中放置的位置。
-
假设您知道如何使用钩子,将它与状态钩子一起使用并更新效果中的状态。在渲染本身传递状态值,可以是状态钩子参数中设置的默认值。
-
如果你不了解 hooks,请先学习
标签: reactjs asynchronous react-redux react-async