Reactjs 使用react apollo UseHook处理错误
我一直在想这个问题,但还没有找到一个强有力的答案。我正在尝试使用useMutation钩子执行登录变异 TLDR;我想知道传入的onError选项与USEMANTIONE提供给我的错误之间的区别是什么 这是我的代码片段Reactjs 使用react apollo UseHook处理错误,reactjs,graphql,react-apollo,apollo-client,Reactjs,Graphql,React Apollo,Apollo Client,我一直在想这个问题,但还没有找到一个强有力的答案。我正在尝试使用useMutation钩子执行登录变异 TLDR;我想知道传入的onError选项与USEMANTIONE提供给我的错误之间的区别是什么 这是我的代码片段 const [login, { data, loading, error }] = useMutation(LOGIN_QUERY, { variables: { email, password },
const [login, { data, loading, error }] = useMutation(LOGIN_QUERY, {
variables: {
email,
password
},
onError(err) {
console.log(err);
},
});
在服务器端,我有一封预设/硬编码的电子邮件用于登录,我没有使用Apollo或任何其他客户端。在这个登录变体的解析程序中,如果电子邮件与使用不同,我只会抛出一个错误
throw new Error('Invalid Email');
现在我想在客户端处理这个错误(React)。但我担心的是,如果我使用从UseVariation钩子返回的“error”,并尝试以这种方式显示错误
render() {
...
{error && <div> Error occured </div>}
...
}
render(){
...
{发生错误&&错误}
...
}
错误会在UI中更新,但随后立即反应会显示一个包含未处理拒绝(错误)的屏幕:Graphql错误:我的自定义错误消息
但是,如果我使用onError传入选项来使用mutate函数,那么它不会显示这个屏幕,我可以对错误执行任何我想要的操作
我想知道传入的onError选项与useMutation提供给我的错误之间到底有什么区别,以及为什么当onError未使用时,React会向我显示错误屏幕
谢谢 Apollo通过其API暴露了两种错误:GraphQL错误,作为响应的一部分返回为
错误
,与数据一起返回,以及请求失败时发生的网络错误。当无法访问服务器或响应状态不是200时,将发生网络错误——响应中有错误的查询的状态仍然是200。但是,例如,无效查询将导致Apollo客户端出现400状态和网络错误
Apollo客户端实际上提供了四种不同的方法来处理变异错误:
1.)调用钩子返回的mutate
函数将返回一个承诺。如果请求成功,承诺将解析为包含服务器返回的数据的响应对象。如果请求失败,承诺将以错误拒绝。这就是为什么您会在控制台中看到一条“未处理的拒绝”消息——您需要处理被拒绝的承诺
login()
.then(({ data }) => {
// you can do something with the response here
})
.catch(e => {
// you can do something with the error here
})
或使用异步/等待语法:
try {
const { data } = await login()
} catch (e) {
// do something with the error here
}
默认情况下,承诺将在上拒绝GraphQL错误或网络错误。但是,通过将设置为“忽略”
或“全部”
,承诺将仅拒绝网络错误。在这种情况下,GraphQL错误仍然可以通过response对象访问,但是Promise会解决
2.)当您提供onError
功能时,出现上述情况的唯一例外。在这种情况下,承诺将始终得到解决,而不是拒绝,但如果出现错误,将调用带有结果错误的onError
。您设置的errorPolicy
也适用于此处--onError
将始终为网络错误调用,但在使用none
的默认errorPolicy
时,将仅与GraphQL错误一起调用。使用onError
相当于捕获被拒绝的承诺——它只是将错误处理程序从mutate
函数的调用位置移动到钩子的调用位置
3.)除了mutate
函数外,useMutation
钩子还返回一个结果对象。此对象还公开了运行变异时遇到的任何错误。与上面编写的错误处理函数不同,这个error
对象表示应用程序状态。以这种方式公开的错误
和数据
对象都是为了方便起见而存在的。它们相当于这样做:
const [mutate] = useMutation(YOUR_MUTATION)
const [data, setData] = useState()
const [error, setError] = useState()
const handleClick = async () => {
try {
const { data } = await mutate()
setData(data)
catch (e) {
setError(e)
}
}
当您希望您的UI反映存在错误的事实时,这样的错误状态非常有用。例如,您可以更改元素的颜色,直到突变运行时没有错误。您不必自己编写上述样板文件,只需使用提供的结果对象即可
const [mutate, { data, error }] = useMutation(YOUR_MUTATION)
注意:虽然您可以使用暴露的错误状态来更新UI,但这样做并不能代替实际处理错误。您必须提供onError
回调或catch
错误,以避免有关未处理承诺拒绝的警告
4.)最后,您还可以使用为请求添加全局错误处理。例如,这允许您显示错误对话框,而不管请求在应用程序中的何处发出
在应用程序中使用哪种方法在很大程度上取决于您尝试执行的操作(全局与本地、状态与回调等)。大多数应用程序将使用多种错误处理方法
const [mutationHandler, { data, loading }] = useMutation(YOUR_MUTATION, {
onError: (err) => {
setError(err);
}
});
有了它,我们可以访问具有加载状态和正确错误处理的数据,以避免在控制台/未处理的承诺拒绝中出现任何错误。精彩而全面的解释。你赢得了很高的支持率。所有这些信息都应该在阿波罗的文档中。非常详细的回答。在文档中包含这一点可能非常棒(:这正是我需要知道的,并展示了阿波罗的质量和灵活性。如果你阅读文档,你会感到困惑。阅读本文,你会感到兴奋。