Error handling reactjs try catch在渲染中不捕获子错误

Error handling reactjs try catch在渲染中不捕获子错误,error-handling,reactjs,Error Handling,Reactjs,我试图将错误捕捉添加到组件的渲染函数中。当我在实际渲染函数中抛出错误时,这可以正常工作,但是如果组件的子级中存在错误,try不会捕获错误(或者它们被子组件错误处理程序截获,我不确定?) 是否存在将错误强制到父级的方法 const SimpleComponent = React.createClass({ render: function(){ try{ throw 'new error' return <div>

我试图将错误捕捉添加到组件的渲染函数中。当我在实际渲染函数中抛出错误时,这可以正常工作,但是如果组件的子级中存在错误,try不会捕获错误(或者它们被子组件错误处理程序截获,我不确定?)

是否存在将错误强制到父级的方法

const SimpleComponent = React.createClass({
    render: function(){
        try{
            throw 'new error'
            return <div>{this.props.children}</div>
        }catch(e){
            console.log('error', e);        
        }
    }
})
const SimpleComponent=React.createClass({
render:function(){
试一试{
抛出“新错误”
返回{this.props.children}
}捕获(e){
console.log('error',e);
}
}
})
以上工作

const SimpleComponent = React.createClass({
    render: function(){
        try{
            return <div>{this.props.children}</div>
        }catch(e){
            console.log('error', e);        
        }
    }
})

const ChildComponent = React.createClass({
    render: function(){
        throw 'child error'
    }
})

<SimpleComponent>
    <ChildComponent />
</SimpleComponent>
const SimpleComponent=React.createClass({
render:function(){
试一试{
返回{this.props.children}
}捕获(e){
console.log('error',e);
}
}
})
const ChildComponent=React.createClass({
render:function(){
抛出“子错误”
}
})

上面的内容无法捕获

您可以利用React的BatchingStrategy API轻松地在所有React代码周围包装一个
try/catch
。与window.onerror相比,这种方法的好处在于,在所有浏览器中都可以获得很好的堆栈跟踪。即使是像Microsoft Edge和Safari这样的现代浏览器也不提供对
window.onerror
的堆栈跟踪

请注意,此解决方案并不总能防止React进入不良状态。但是,此解决方案至少允许您处理错误,例如显示错误横幅/模式,或向服务发送堆栈跟踪错误日志

以下是React 15.4的外观:

import ReactUpdates from "react-dom/lib/ReactUpdates";
import ReactDefaultBatchingStrategy from "react-dom/lib/ReactDefaultBatchingStrategy";

let isHandlingError = false;
const ReactTryCatchBatchingStrategy = {
  // this is part of the BatchingStrategy API. simply pass along
  // what the default batching strategy would do.
  get isBatchingUpdates () { return ReactDefaultBatchingStrategy.isBatchingUpdates; },

  batchedUpdates (...args) {
    try {
      ReactDefaultBatchingStrategy.batchedUpdates(...args);
    } catch (e) {
      if (isHandlingError) {
        // our error handling code threw an error. just throw now
        throw e;
      }

      isHandlingError = true;
      try {
        // replace this with whatever error handling logic you like.
        // e.g. dispatch redux action notifying the app that an error occurred:
        // `store.dispatch({type: "EXCEPTION", payload: e});`
        console.error(e);
      } finally {
        isHandlingError = false;
      }
    }
  },
};

ReactUpdates.injection.injectBatchingStrategy(ReactTryCatchBatchingStrategy);
全文如下:

我建议在您的父组件中使用(当前)不稳定的生命周期事件
unstable\u handleError

public unstable_handleError(err: any) {

  this.setState({
    error: err
  });

}
错误钩子很可能在将来的版本中成为官方API。 有关详细信息,请参阅本期


使用react 16中的componentDidCatch()方法


查看更多信息

我不认为这就是
render()
的工作原理。您应该避免使用任何
render()
方法。任何可能抛出的工作都应该放在其他地方。您应该使用Prop验证(PropTypes)来确保组件正确呈现,您的示例不是try-catch-try-stack-to-React的内置实现的正确用例“您应该真正避免抛出任何render()=>可能已经有来自其他地方的组件可能会通过您描述的确切问题Hey Byron。这很好,但是你在哪里实际使用它呢?这在应用程序中的哪个位置?@jamesemanon您可以将此代码段粘贴到代码库中的任何位置。代码段中的关键行是
ReactUpdates.injection.injectBatchingStrategy(reactRryCatchBatchingStrategy)
在我们的代码库中,我们在调用
ReactDOM.render()
+1之前,将注入行放入我们的应用程序初始化文件中。我明白了,这对我很有用,谢谢!但是函数
apptriggederror
在这里或链接文章中没有提到。我想你最好把它拿出来,换成例如
控制台。错误(e)
或类似的东西(但保留你的短语“用你喜欢的错误处理逻辑替换它”)。@TylerCollier good call!是的,把它留在那里只是一个confusion@ByronWong当我把它添加到我的App.js中时,我得到了一个错误“ReactUpdates:必须提供一个批处理策略”,你能确认它是否捕捉到了孩子们的错误吗?它对我不起作用。只有在初始渲染抛出错误时才会捕获。如果更新导致错误的渲染,它将无法工作