react 错误边界
If you have built a React app at any point in your programming career, you probably have experienced an error at some point that was cryptic and did not provide any meaningful context on what actually happened.
如果您在编程生涯中的任何时候都构建了一个React应用,那么您可能在某个时候遇到了一个错误,该错误是一个隐秘的,并且没有提供关于实际发生的任何有意义的上下文。
This probably means the error occured at some point in the application and our React component did not handle the error gracefully, well mostly because it was none of its business to make sure the entire app holds.
这可能意味着该错误在应用程序中的某个时刻发生,并且我们的React组件无法优雅地处理该错误,主要是因为确保整个应用程序正常运行与它无关。
引入错误边界 ( Introducing Error Boundaries )
A JavaScript error in a part of the UI shouldn’t break the whole app. To solve this problem for React users, React 16 introduces a new concept of an “error boundary”.
用户界面中JavaScript错误不应破坏整个应用程序。 为了为React用户解决此问题,React 16引入了“错误边界”的新概念。
An Error Boundary is a React component that catches errors within it's children and does something meaningful with them such as post them to an error logging service or display a fallback UI for the specific child while maintaining the rest of the React app's sanity.
Error Boundary是一个React组件,它可以捕获其子级中的错误并对其进行有意义的处理,例如将其发布到错误记录服务或为特定子级显示后备UI,同时保持其余的React应用程序的健全性。
Therefore, for a block of functionality to be covered by Error Boundaries, it has to be a child of one in the first place.
因此,对于要由“错误边界”覆盖的功能块,它首先必须是一个子元素。
Before we get started on an example of how you can use the React 16, beware that Error Boundaries will not catch errors in:
在我们开始使用如何使用React 16的示例之前,请注意错误边界不会捕获以下错误:
- Event handlers. ** - Use a
try / catch
block instead within event handlers. 2. Asynchronous code** 事件处理程序。 **-在事件处理程序中使用try / catch
块。 2.异步代码** - Server side rendering 服务器端渲染
- Errors within the Error Boundary Component. - You cannot save others if you cannot save yourself first. 错误边界组件内的错误。 -如果不能先保存自己,就不能保存其他人。
componentDidCatch() ( componentDidCatch() )
Lifecycle methods are special functions that are invoked at different stages in the life of a component. These stages can be categorized into Mounting, Updating, Unmounting and Error handling.
生命周期方法是在组件生命周期的不同阶段调用的特殊功能。 这些阶段可以分为安装 , 更新 , 卸载和错误处理 。
For a component to be considered an Error Boundary, it has to make use of the componentDidCatch()
lifecycle method to handle errors. It works in the same way that Javascript's try/catch
works.
对于被认为是错误边界的组件,它必须利用componentDidCatch()
生命周期方法来处理错误。 它的工作方式与Java代码的try/catch
相同。
the componentDidCatch
method is invoked with the an error
and info
parameters that contain more context on the thrown error.
使用error
和info
参数调用componentDidCatch
方法,该参数包含有关引发的错误的更多上下文。
在哪里使用它们 ( Where To Use Them )
Just like the granularity of React component is entirely up to you, Error Boundaries can be as specific as you want them to be. You can have a top level Error Boundary that prevents the app from crashing due to unexpected occurences and displaying a more suitable message.
就像React组件的粒度完全取决于您一样,错误边界的具体程度可以随您的要求而定。 您可以具有顶级错误边界,以防止应用程序由于意外事件而崩溃并显示更合适的消息。
For this article, we will be creating an Error Boundary that only wraps a specific functionality with errors of our own design.
对于本文,我们将创建一个错误边界,该边界仅包装具有我们自己设计错误的特定功能。
创建错误边界 ( Creating An Error Boundary )
To get started, we will create a simple Component that only allows you to enter upto five characters into a input field. Any more than that and we break the internet. Feel free to try out in of the freely available online editors, I personally use Codepen.io.
首先,我们将创建一个简单的组件,仅允许您在输入字段中输入最多五个字符。 除此之外,我们还可以中断互联网。 随意试用免费提供的在线编辑器,我个人使用Codepen.io 。
class FiveMax extends React.Component {
constructor(props) {
super(props);
this.state = { value: ''}
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({ value: e.target.value})
}
render() {
if(this.state.value.length > 5) {
throw new Error('You cannot enter more than five characters!');
}
return (
<div>
<label>Type away: </label>
<input type="text" value={this.state.value} onChange={this.handleChange} />
</div>
);
}
}
ReactDOM.render(<FiveMax />, document.getElementById('root'));
If you type in more than five characters, you should get a big shiny error on your console.
如果您输入的字符超过五个,则控制台上会出现一个很大的闪亮错误。

You will also notice that your input box disappers due to the error. Perfect! Let's create an Error Boundary. I'll call mine Shield.
您还会注意到,输入框由于该错误而消失。 完善! 让我们创建一个错误边界。 我称呼我为Shield。
class Shield extends React.Component {
constructor(props) {
super(props);
// Add some default error states
this.state = {
error: false,
info: null,
};
}
componentDidCatch(error, info) {
// Something happened to one of my children.
// Add error to state
this.setState({
error: error,
info: info,
});
}
render() {
if(this.state.error) {
// Some error was thrown. Let's display something helpful to the user
return (
<div>
<h5>Sorry. More than five characters!</h5>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.info.componentStack}
</details>
</div>
);
}
// No errors were thrown. As you were.
return this.props.children;
}
}
Nothing special right? The only new thing that we have in this component that you probably haven't used before is the componentDidCatch
method.
没什么特别的权利吗? 您可能以前从未使用过的此组件中唯一的新东西是componentDidCatch
方法。
When an error is thrown in any of it's children, the error state will be updated and a meaningful error displayed. Otherwise, the Shield
will go ahead and display the children as usual.
在任何子级中引发错误时,错误状态将更新并显示有意义的错误。 否则, Shield
将继续进行,并照常显示孩子。
实现错误边界 ( Implementing The Error Boundary )
To start using the Error Boundary, we will look at two separate scenarios.
要开始使用“错误边界”,我们将研究两个单独的场景。
方案一:同一错误边界内的两个组件 (Scenario One: Two Components within the same Error Boundary)
In a situation where you have two Components within the same Error Boundary and an error is thrown in one of the Components, they are both affected due to the structure of the render
method in our Shield
component.
如果您在同一个错误边界内有两个组件,并且在其中一个组件中引发了错误,则它们都会受到Shield
组件中render
方法结构的影响。
To try this out, we will add two FiveMax
components inside our Shield
Error Boundary.
为了尝试这一点,我们将在Shield
Error Boundary中添加两个FiveMax
组件。
// Shield Component
// FiveMax Component
function App() {
return (
<div>
<h3>Two children under one error boundary. If one crashes. Both are affected!</h3>
<Shield>
<FiveMax />
<FiveMax />
</Shield>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
When you try typing more than five characters into any of the fields, an error is logged on the console and we get a pleasing and more informative message displayed to the user in place of both components.
当您尝试在任何字段中键入五个以上的字符时,控制台上会记录一个错误,并且在这两个组件的位置,我们会看到一条令人愉悦且内容丰富的消息,向用户显示。

This is all good but we did not need to lose the other component that did not throw any errors. Let's fix that!
一切都很好,但是我们不必丢失没有引发任何错误的其他组件。 让我们解决这个问题!
方案二:两个组件,每个组件都有自己的错误边界 (Scenario Two: Two Components, each of them with it's own Error Boundary)
Now to prevent what happened in the scenario one, we will have each of the FiveMax
components in their own Shield
Error Boundary.
现在,为了防止场景一发生的情况,我们将每个FiveMax
组件都置于各自的“ Shield
错误边界”中。
// Shield Component
// FiveMax Component
function App() {
return (
<div>
<h3>Two children, each with their own Error Boundary. One crashes, the other is not affected</h3>
<Shield><FiveMax /></Shield>
<Shield><FiveMax /></Shield>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
Now try typing more than five characters in any of the components. Notice anything? Instead of losing both components to the error, you only lose the Component that is affected. In place of the affected component only. The rest of the App remains intact!
现在尝试在任何组件中键入五个以上的字符。 注意到什么了吗? 您不会丢失该错误的两个组件,而只会丢失受影响的组件。 仅代替受影响的组件。 该应用程序的其余部分保持不变!

You can try out both scenarios in the Pen below.
您可以在下面的笔中尝试这两种情况。
See the Pen Five Max by John Kariuki (@johnkariuki) on CodePen.
见笔五个最大的约翰·Kariuki( @johnkariuki上) CodePen 。
结论 ( Conclusion )
How you use error logs entirely depends on what you want to achieve. You can have a separate Error Boundary for your navigation bar and a different one for the rest of your app so that if something goes wrong in your App's functionality, the navigation remains usable!
错误日志的使用方式完全取决于要实现的目标。 您可以为导航栏设置一个单独的“错误边界”,为应用程序的其余部分设置一个不同的“错误边界”,这样,如果您的应用程序功能出现问题,导航仍然可用!
Remember that if your Error Boundary throws an error, anything in it's child component tree is affected. So be careful when coming up with an one so that it is not prone to errors
请记住,如果您的错误边界抛出错误,则其子组件树中的所有内容都会受到影响。 因此,在提出一个建议时要小心,以免出错
翻译自: https://scotch.io/tutorials/error-handling-in-react-16-using-error-boundaries
react 错误边界