Reactjs 为什么不应该';我是否使用catch()来处理React-useEffect API调用中的错误?
在React文档的此页上: 代码注释说 注意:在这里处理错误而不是catch()块很重要,这样我们就不会从组件中的实际错误中吞下异常 …关于处理第二个Reactjs 为什么不应该';我是否使用catch()来处理React-useEffect API调用中的错误?,reactjs,react-hooks,use-effect,Reactjs,React Hooks,Use Effect,在React文档的此页上: 代码注释说 注意:在这里处理错误而不是catch()块很重要,这样我们就不会从组件中的实际错误中吞下异常 …关于处理第二个的第二个参数中的错误。然后在fetch之后处理。文档中的完整片段是: useffect(()=>{ 取回(“https://api.example.com/items") .then(res=>res.json()) .那么( (结果)=>{ setIsLoaded(真); 设置项目(结果); }, //注意:这里处理错误很重要 //而不是一个c
的第二个参数中的错误。然后在fetch
之后处理。文档中的完整片段是:
useffect(()=>{
取回(“https://api.example.com/items")
.then(res=>res.json())
.那么(
(结果)=>{
setIsLoaded(真);
设置项目(结果);
},
//注意:这里处理错误很重要
//而不是一个catch()块,这样我们就不会吞咽
//组件中实际错误的例外情况。
(错误)=>{
setIsLoaded(真);
设置错误(错误);
}
)
}, [])
它没有详细说明这个建议,我已经看到许多使用catch
处理API调用错误的React代码示例。我尝试过谷歌搜索,但找不到任何澄清
有人能给我一个更详细的解释,为什么我不应该使用catch
来处理在useffect
钩子中进行fetch
API调用时出现的错误
或者在某些情况下可以这样做,但在其他情况下不行
组件中的“吞咽异常[…]是什么意思”
此规则/指南是否适用于所有React,还是仅适用于API调用
或者只需使用useffect
hook或componentDidMount
lifecycle方法?我能找到的一切似乎都可以追溯到2016年左右。我将逐字引用其中的内容,因为以前似乎没有在堆栈溢出中介绍过它,并且它非常彻底地解释了这一点:
您的catch()
处理程序将捕获then()中抛出的任何错误
之前的链,包括由于
setState()
调用
即使您不直接使用setState
,也可能会遇到同样的问题
如果您调用的其他代码使用它(例如,Reduxdispatch()
)
如果您不想捕获由setState()
引起的错误,并且希望
只捕获网络故障(让我们想象一下您的Promise.resolve()
实际上是一个fetch()
),您想使用第二个then()
参数
相反:
在这种情况下,除非在链的后面执行catch()
,否则
render()
将是未捕获的,并且具有良好的承诺polyfill(或
Chrome和其他浏览器中的本机承诺),显示
编辑:根据@Martin的回答,我去测试了这一点,我可以确认这似乎不再是一个相关问题。从v16.0起,React的任何版本都不会捕捉到来自setState
的渲染错误,而且由于useState
仅在v16.8中引入,因此这似乎不可能成为挂钩的问题
下面是一个示例,演示了旧版本React中的原始问题。这是示例作者的复制粘贴错误。
第一个示例使用基于类的组件的组件状态:this.setState()
导致同步重新呈现(或者至少2016年的react v15.0就是这种情况,不确定它今天是否成立)。因此,警告注释和使用第二个参数。然后(onResolve,onReject)
是合理的。
第二个示例使用函数组件的useState
钩子:setState
不会导致同步重新渲染,只会导致异步重新渲染。因此,警告注释和使用第二个参数来。然后(onResolve,onReject)
是不合理的
为了说明这一点:使用useState
hooks,您可以调用多个更新程序,它们只在一次重新渲染中生效
const [a, setA] = useState();
const [b, setB] = useState();
const [c, setC] = useState();
const updateState = () => {
setA('foo');
setB('bar');
setC('buz');
// will only cause one single re-render
}
因此,使用catch是非常好的
useEffect(() => {
fetch("https://api.example.com/items")
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result);
}
)
.catch(
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, [])
因此,如果我理解正确,那么这个注释是错误地留在示例中的,我完全没有理由不使用catch()来处理React-useEffect API调用中的错误。太好了,谢谢。是的,没错。您可以使用.catch()
,我认为这可以提高代码的清晰度。感谢您回答我的问题,并测试和确认其他答案。
const [a, setA] = useState();
const [b, setB] = useState();
const [c, setC] = useState();
const updateState = () => {
setA('foo');
setB('bar');
setC('buz');
// will only cause one single re-render
}
useEffect(() => {
fetch("https://api.example.com/items")
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result);
}
)
.catch(
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, [])