【发布时间】:2020-01-21 04:44:16
【问题描述】:
在使用 apollo graphql 的渲染道具方式中。我曾经能够做到这一点:
export const CsmartQuery = (({ children, isShowGenericErrorSnackBarForError, ...rest }) => (
<Query errorPolicy="all"
{...rest} >
{result =>
<GraphQLErrorHandler isShowGenericErrorSnackBarForError={isShowGenericErrorSnackBarForError}
result={result}>
{(transformedResult) => children(transformedResult)}
</GraphQLErrorHandler>
}
</Query>
))
我的 GraphQLErrorHandler,用于检查错误,如果它是服务器错误(我的通用捕获所有错误),那么我会向用户显示一个错误快餐栏。我还处理错误,去掉所有不需要的东西,只向孩子们发送一个代码和一条消息来处理。这是完整的 GraphQLErrorHandler 组件
import React from 'react';
import { showErrorSnackBarAction } from '../redux/appActions'
import { connect } from 'react-redux'
const transformError = (e) => {
if(e.networkError ||
((e.graphQLErrors || []).length === 0) ||
!e.graphQLErrors[0].extensions ||
e.graphQLErrors[0].extensions.code === 'SERVER_ERROR') {
return {
message: 'An error occurred while processing your request. Please try again',
code: 'SERVER_ERROR'
}
}
return {
message: e.graphQLErrors[0].message,
code: e.graphQLErrors[0].extensions.code,
}
};
const transformErrorsInResult = (result) => {
return {...result, error: result.error ? transformError(result.error) : undefined}
}
const GraphQLErrorHandler = ({result, isShowGenericErrorSnackBarForError, showErrorSnackBarAction, children}) => {
const [transformedResult, setTransformedResult] = React.useState(transformErrorsInResult(result))
React.useEffect(() => {
const newResult = transformErrorsInResult(result)
if(newResult.error && isShowGenericErrorSnackBarForError) {
showErrorSnackBarAction({message: newResult.error.message})
}
setTransformedResult(() => newResult)
}, [result, isShowGenericErrorSnackBarForError, showErrorSnackBarAction])
return (
children(transformedResult)
)
}
export default connect(null, { showErrorSnackBarAction })(GraphQLErrorHandler);
而且我不使用来自 apollo 的 Query,而是到处使用 CsmartQuery 组件。
<CsmartQuery query={companyAddressQuery} variables={{ companyId: company.id }} isShowGenericErrorSnackBarForError>
{({ data, loading, error }) => {
if (error) return null
if (loading)
return (
<Container textAlign="center">
<Loader active />
</Container>
)
return <AddressDetailsWrapper companyAddresses={data.companyAddresses || []} company={company} {...rest} />
}}
</CsmartQuery>
如何使用 useQuery 挂钩并能够以通用方式处理错误?我希望转换错误并在需要时显示一个快餐栏。最好以一种我不必在每个组件中重复代码的方式。
【问题讨论】: