异步在React Functional Component中引发错误



我试图在以下功能组件中使用异步,但抛出错误

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)

下面是返回true或false 的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";在函数"中被调用;"已验证";既不是React函数组件,也不是自定义的React Hook函数React Hook/钩子规则第194:3行:React Hook";useEffect";在函数"中被调用;"已验证";既不是React功能组件,也不是自定义的React Hook功能React Hook/钩子规则

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)

钩子必须命名为useXxx,否则esint将抱怨。此外,钩子必须在函数组件的顶层调用。

您可以在useState()默认值param和效果中调用verifyToken()。如果这是一个漫长的过程,你应该只在效果上做。

如果您想在组件的生命周期中只调用useVerify()中的verifyToken()一次,则应该在useEffect()依赖数组中添加一个空数组

function useVerified(auth){
const [verified, setVerifiedValue] = useState();
useEffect(() => {
const doVerify = async () => {
setVerifiedValue(await verifyToken(auth.values))
}
doVerify()
}, [])
return verified;
}
const RouteConfig =  ({ component: Component, fullLayout, user, auth, ...rest}) => {
const verified = useVerified(auth);
return <Route
{...rest} 
render={props => {
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)

以下操作有效吗?

const NONE = {};
const RouteConfig = ({
component: Component,
fullLayout,
user,
auth,
...rest
}) => (
<Route
{...rest}
render={(props) => {
const [verified, setVerified] = React.useState(NONE);
React.useEffect(
() => verifyToken(auth.values).then(setVerified),
[]
);
if (verified === NONE) {
return null;
}
return (
<ContextLayout.Consumer>
{(context) => {
let LayoutTag =
fullLayout === true
? context.fullLayout
: context.state.activeLayout ===
'horizontal'
? context.horizontalLayout
: context.VerticalLayout;
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>
);
}}
/>
);

相关内容

最新更新