react 错误边界

Have you seen these in your console?

您是否在控制台中看到了这些?

Cannot read property ‘getHostNode’of null ?
TypeError: Cannot read property ‘_currentElement’ of null ?

If you maintain a React application, you know that this class of error messages can be among the most frustrating and difficult to resolve. Typical symptoms include stack traces that thread through dark regions of the React internals, devoid of hope or references to even a single line of your own code:

如果您维护一个React应用程序,您就会知道这类错误消息可能是最令人沮丧且难以解决的错误消息。 典型的症状包括堆栈跟踪 ,这些跟踪遍历了React内部的黑暗区域,没有希望,甚至没有引用到您自己的代码的一行:

TypeError: Cannot read property 'getHostNode' of null ?at getHostNode(~/react/lib/ReactReconciler.js:64:0)at getHostNode(~/react/lib/ReactCompositeComponent.js:383:0) ?at getHostNode(~/react/lib/ReactReconciler.js:64:0)at getHostNode(~/react/lib/ReactChildReconciler.js:114:0)?at updateChildren(~/react/lib/ReactMultiChild.js:215:0)at _reconcilerUpdateChildren(~/react/lib/ReactMultiChild.js:314:0)at _updateChildren(~/react/lib/ReactMultiChild.js:301:0)at updateChildren(~/react/lib/ReactDOMComponent.js:942:0)at _updateDOMChildren(~/react/lib/ReactDOMComponent.js:760:0) ?at updateComponent(~/react/lib/ReactDOMComponent.js:718:0)at receiveComponent(~/react/lib/ReactReconciler.js:126:0)at receiveComponent(~/react/lib/ReactCompositeComponent.js:751:0) ?at _updateRenderedComponent(~/react/lib/ReactCompositeComponent.js:721:0)at _performComponentUpdate(~/react/lib/ReactCompositeComponent.js:642:0)at updateComponent(~/react/lib/ReactCompositeComponent.js:544:0)at receiveComponent(~/react/lib/ReactReconciler.js:126:0) ?at receiveComponent(~/react/lib/ReactCompositeComponent.js:751:0)at _updateRenderedComponent(~/react/lib/ReactCompositeComponent.js:721:0)at _performComponentUpdate(~/react/lib/ReactCompositeComponent.js:642:0)at updateComponent(~/react/lib/ReactCompositeComponent.js:544:0)at receiveComponent(~/react/lib/ReactReconciler.js:126:0)  ?at receiveComponent(~/react/lib/ReactCompositeComponent.js:751:0)at _updateRenderedComponent(~/react/lib/ReactCompositeComponent.js:721:0)at _performComponentUpdate(~/react/lib/ReactCompositeComponent.js:642:0)at updateComponent(~/react/lib/ReactCompositeComponent.js:544:0) ?at receiveComponent(~/react/lib/ReactReconciler.js:126:0)at receiveComponent(~/react/lib/ReactCompositeComponent.js:751:0) ?at _updateRenderedComponent(~/react/lib/ReactCompositeComponent.js:721:0)at _performComponentUpdate(~/react/lib/ReactCompositeComponent.js:642:0)at updateComponent(~/react/lib/ReactCompositeComponent.js:558:0)at performUpdateIfNecessary(~/react/lib/ReactReconciler.js:158:0)at performUpdateIfNecessary(~/react/lib/ReactUpdates.js:151:0) ?at call(~/react/lib/Transaction.js:138:0)at call(~/react/lib/Transaction.js:138:0)at call(~/react/lib/ReactUpdates.js:90:0)at perform(~/react/lib/ReactUpdates.js:173:0)at call(~/react/lib/Transaction.js:204:0)at closeAll(~/react/lib/Transaction.js:151:0)at perform(~/react/lib/ReactDefaultBatchingStrategy.js:63:0) ?at batchedUpdates(~/react/lib/ReactUpdates.js:98:0)at batchedUpdates(~/react/lib/ReactEventListener.js:150:0)

If this type of stack trace from a React error is a familiar sight to you, I’ve got some good news for you!

如果您对React错误的这种堆栈跟踪类型感到熟悉,那么我对您来说有个好消息!

向React 16打个招呼 ( Say Hello to React 16 )

React 16 was officially released on September 26, 2017. React 16 is an API-compatible, under-the-hood rewrite of the React internals with ambitious goals like enabling asynchronous or preemptive rendering and providing new tools (with sweet names) for elegantly expressing component hierarchies, like fragments and portals, that are cumbersome today. Another goal of the architecture is handling errors with a new, more correct and rigorous strategy.

React 16于2017年9月26日正式发布。React16是一个兼容API的,对React内部的底层重写,其雄心勃勃的目标包括启用异步或抢占式渲染以及提供新工具(带有甜美名称)以优雅地表达如今,繁琐的组件层次结构(例如片段和门户)非常麻烦。 该体系结构的另一个目标是使用新的,更正确和严格的策略来处理错误。

This strategy means React 16 prevents situations where an error inside of a render call causes an invalid state and results in undefined behavior or confusing errors (like our good friend Cannot read property 'getHostNode' of null) by unmounting the entire component tree when errors are thrown inside render or lifecycle methods.

这种策略意味着React 16通过在错误发生时卸载整个组件树来防止渲染调用内部的错误导致无效状态并导致未定义的行为或令人困惑的错误(例如我们的好朋友Cannot read property 'getHostNode' of null )的情况。抛出在render或生命周期方法中。

Failing more aggressively on these errors means not allowing the application to continue running in a corrupted state — reducing the distance between where you trip (where the real problem occurs) and where you hit the ground (where React blows up because its internal bookkeeping is corrupt). This makes certain errors in React components easier to understand and fix.

无法更积极地解决这些错误,意味着不允许应用程序在损坏状态下继续运行-缩短行程(发生真正问题的地方)与触地(由于内部簿记损坏导致React崩溃)之间的距离)。 这使得React组件中的某些错误更容易理解和修复。

However, it also means that existing problems that may have been failing silently or non-catastrophically will now cause the entire app to unmount. Yikes!

但是,这也意味着可能已经静默或非灾难性地失败的现有问题现在将导致整个应用程序卸载。 kes!

The solution to this is React 16’s new tool for explicitly handling error propagation, error boundaries. Error boundaries are analogous to try{ }catch(e){ } statements, but they live inside and are scoped by component hierarchy instead of inside a given block of synchronous JavaScript.

解决方案是React 16的新工具,用于显式处理错误传播,错误边界。 错误边界类似于try{ }catch(e){ }语句,但是它们位于内部,并且受组件层次结构限制,而不是在给定的同步JavaScript块内。

Error boundaries exist because ↓↓↓ doesn’t work with the JSX rendering model:

存在错误边界是因为↓↓↓不适用于JSX渲染模型:

@media (max-width: 1280px) { .go-go-gadget-react img:first-child { display: none; } }@media (max-width: 780px) {.go-go-gadget-react { flex-direction: column; }.go-go-gadget-react img { margin-left: 0 !important; margin-bottom: 12px !important; }.header-thingy { margin-top: 20px; }.button-thingy { margin-left: 0 !important; margin-top: 12px !important; }} @media (max-width: 1280px) { .go-go-gadget-react img:first-child { display: none; } }@media (max-width: 780px) {.go-go-gadget-react { flex-direction: column; }.go-go-gadget-react img { margin-left: 0 !important; margin-bottom: 12px !important; }.header-thingy { margin-top: 20px; }.button-thingy { margin-left: 0 !important; margin-top: 12px !important; }}

<div>{ try {<CoolComplicatedComponent/>} catch(error){handleChildError(error)}}
</div>

By using error boundaries, you can isolate sections of your app’s component tree from errors in other sections, for instance, allowing your media player to continue running smoothly when the comment section crashes. This is without sacrificing React 16’s more predictable behavior or risking the possible exposure of corrupted state or undefined behavior. It’s a big improvement for your application’s stability.

通过使用错误边界,您可以将应用程序组件树的各个部分与其他部分中的错误隔离开,例如,当注释部分崩溃时,允许媒体播放器继续平稳运行。 这不会牺牲React 16的更可预测的行为,也不会冒可能暴露出损坏状态或未定义行为的风险。 这对您的应用程序的稳定性有很大的改进。

开始使用错误边界 ( Start Using Error Boundaries )

Error boundaries are something that every large React application should use to improve error resiliency. The API surface of error boundaries is simple: any React component becomes an error boundary when it implements the new lifecycle method, componentDidCatch(error, info). This will be called with any uncaught error that bubbles up from the component’s children’s lifecycle methods, constructors, or render methods (but not the component’s own errors).

错误边界是每个大型React应用程序都应使用的错误边界,以提高错误弹性。 错误边界的API表面很简单:任何React组件在实现新的生命周期方法componentDidCatch(error, info)时都会成为错误边界。 这将被任何未捕获的错误调用,该错误会从组件的子级生命周期方法,构造函数或渲染方法中冒出来(但不是组件自身的错误)。

<div><ExampleBoundary><h2>Sidebar</h2><Widget/></ExampleBoundary><p> This content won't unmount when Widget throws. </p>
</div>

<ExampleBoundary> is a React component that implements componentDidCatch (there’s an example further below).

<ExampleBoundary>是一个实现componentDidCatch的React组件(下面还有一个示例)。

发现错误时该怎么办? ( What to do when you catch errors? )

You’re allowed to do whatever you see fit in componentDidCatch. But after it has been triggered, you can’t render this.props.children, and you must replace it with some sort of fallback UI. This fallback might mean rendering a heartfelt apology, a debug view, a feedback form, a link to support, or a funny GIF. It could also mean just discreetly rendering nothing at all — it depends on the needs of your application. Just do yourself a favor and try to ensure it’s not something that will throw its own errors!

您可以做任何您认为适合componentDidCatch事情。 但是,在触发它之后,您将无法呈现this.props.children ,并且必须使用某种后备UI替换它。 这种后退可能意味着渲染由衷的道歉,调试视图, 反馈表单 ,支持链接或有趣的GIF。 这也可能意味着仅谨慎地不渲染任何内容,这取决于应用程序的需求。 只是帮自己一个忙,并尝试确保它不会引发自己的错误!

错误边界应该去哪里? (Where should Error Boundaries go?)

Error boundaries are an open-ended tool, and the community is still defining best practices for them. Our advice is to wrap components at the granularity they can be independently useful. This means that when one errors, the others can still accomplish their purpose. Wrapping your page content will protect your header or sidebar navigation components from being unmounted on an error and will give the user an easy way to back out and return to working parts of your application. By contrast, going to the extreme and wrapping every individual input component of a form could leave someone in a UI state that still responds to their input but can’t actually be used to finish their goal.

错误边界是一个开放式工具,社区仍在为它们定义最佳实践。 我们的建议是将组件包装成可以独立使用的粒度。 这意味着,当一个错误发生时,其他错误仍然可以实现其目的。 包装页面内容将保护您的标题或侧边栏导航组件免于因错误而被卸载,并使用户可以轻松地退出并返回到应用程序的工作部分。 相比之下,走极端并包装表单的每个单独的输入组件可能会使某人处于UI状态,该状态仍会响应他们的输入,但实际上不能用来完成他们的目标。

Note: by default, raven.js, Sentry’s JavaScript SDK, carefully instruments built-in methods to try to automatically wrap your code in try/catch blocks. It does this to attempt to capture error messages and stack traces from all your scripts, regardless of which origin they’re served from.

注意:默认情况下, SentryJavaScript SDK raven.js会谨慎地使用内置方法来尝试自动将代码包装在try / catch块中。 它这样做是为了尝试捕获所有脚本中的错误消息和堆栈跟踪信息,而不管它们来自何处。

将错误发送给Sentry! ( Send the errors to Sentry! )

Because error boundaries are analogous to try/catch, exceptions they capture will not automatically be bubbled up to Sentry’s global uncaught error handler in production. Make sure to call Raven.captureException(error) in your componentDidCatch implementations to get insights into these errors and fix them.

因为错误边界类似于try / catch, 所以捕获的异常不会自动冒泡到生产中Sentry的全局未捕获错误处理程序中 。 确保在componentDidCatch实现中调用Raven.captureException(error)以获得对这些错误的了解并进行修复。

Here’s an example of an error boundary component that apologizes and sends a report to Sentry plus gives the user the option to fill out a report of what happened:

这是一个错误边界组件的示例,该组件道歉并向Sentry发送报告,并为用户提供填写所发生情况的报告的选项:

class ExampleBoundary extends Component {constructor(props) {super(props);this.state = { error: null };}componentDidCatch(error, errorInfo) {this.setState({ error });Raven.captureException(error, { extra: errorInfo });}render() {if (this.state.error) {return (<divclassName="snap"onClick={() => Raven.lastEventId() && Raven.showReportDialog()}><img src={oops} /><p>We're sorry — something's gone wrong.</p><p>Our team has been notified, but click here fill out a report.</p></div>);} else {//when there's not an error, render children untouchedreturn this.props.children;}}
}

You can read (or fork!) the complete code here.

您可以在此处阅读(或分叉!) 完整的代码 。

One more cool aspect of componentDidCatch is the second argument, errorInfo. Currently, errorInfo has one property, componentStack, which is a component stack trace. That’s the path through your component tree from your application root all the way to the offending component — something that helps map the error location to your mental model and codebase. Because this information is helpful for triaging and resolving errors, we recommend sending it with Sentry errors as extra data.

componentDidCatch的另一个errorInfo方面是第二个参数errorInfo 。 当前, errorInfo具有一个属性componentStack ,这是一个组件堆栈trace 。 这就是从应用程序根目录到有问题的组件的整个组件树的路径,这有助于将错误位置映射到您的思维模型和代码库。 因为此信息有助于分类和解决错误,所以我们建议将其与Sentry错误一起作为额外数据发送。

As always, you can try Sentry for your React app (it’s 100% open source, too).

与往常一样,您可以为您的React应用尝试Sentry (它也是100%开放源代码)。

That’s it! Happy error monitoring.

而已! 快乐的错误监控 。

翻译自: https://scotch.io/tutorials/how-to-use-error-boundaries-in-react-16

react 错误边界

react 错误边界_如何在React 16中使用错误边界相关推荐

  1. react本地储存_如何在React项目中利用本地存储

    react本地储存 以及为什么要这么做. 本地存储是现代Web浏览器固有的Web API. 它允许网站/应用程序在浏览器中存储数据(简单和有限),从而使数据在以后的浏览器会话中可用. 在开始学习本教程 ...

  2. react 生命挂钩_如何在GraphQL API中使用React挂钩来管理状态

    react 生命挂钩 In this blog post, we are going to learn - 在这篇博客中,我们将学习- What React hooks are什么是React钩子 H ...

  3. react页面保留_如何在React中保留已登录的用户

    react页面保留 If you run a quick Google search for persisting a logged-in user in React (or keeping a us ...

  4. react入门代码_如何在React中构建温度控制应用程序-包括提示和入门代码

    react入门代码 我们正在建立的 (What we're building) In this beginner React project, we're going to learn how to ...

  5. react js 添加样式_如何在React JS Application中添加图像?

    react js 添加样式 Hello! In this article, we will learn how to add images in React JS? I remember when I ...

  6. react 交互_如何在React应用程序中跟踪用户交互

    react 交互 by Faouzi Oudouh 通过Faouzi Oudouh 如何在React应用程序中跟踪用户交互 (How to track user interactions in you ...

  7. react 交互_如何在React中建立动画微交互

    react 交互 Microinteractions guide a user through your application. They reinforce your user experienc ...

  8. react前端显示图片_如何在react项目中引用图片?

    如何在react项目中引用图片?本文码云笔记将为大家整理在react项目中插入图片以及背景图片的方法,希望对需要的小伙伴提供一些参考. 在react项目中插入图片以及背景图片的方法共有2种: 1.im ...

  9. react网格生成_如何在React中构建实时可编辑数据网格

    react网格生成 by Peter Mbanugo 彼得·姆巴努戈(Peter Mbanugo) 如何在React中构建实时可编辑数据网格 (How to Build a Real-time Edi ...

最新文章

  1. 未来智能:人有人用,机有机用
  2. 今年期末微积分考试试题:看看你能够在两个小时内做对几道题?
  3. 政府安全资讯精选 2017年第六期 车联网和移动安全可能成为未来监管重点
  4. JAVA8 Optional新特性和使用详解
  5. POJ 3167 Cow Pattern ★(KMP好题)
  6. MYSQL中group_concat有长度限制!默认1024
  7. 使用jquery解析xml
  8. CentOS6_mini_安装后基本配置
  9. qi接收启动协议_无线充电Qi通信协议分析
  10. Linux 简单教程
  11. 通用版工业制程SPC管理系统,源代码分享
  12. 【HTML】font标签font属性的使用方法
  13. 计算机网络:第四章网络层课后习题及答案(精细版)
  14. torch.nn到底是什么?(精简版)
  15. Mac系统安装/升级 Git
  16. 删除磁盘分区 删除OEM分区
  17. Android Jetpack 架构组件之 Room
  18. 【DataWhale学习】Day10~13-4章决策树——西瓜书学习摘录笔记
  19. CSS 3之菜单的横竖转换
  20. 关于type_info与typeid

热门文章

  1. python 点到线段的距离_点到线段的最短距离
  2. 2021年2G网络全部退网、3G延期退网!中国联通已正式表态
  3. 如何实现APP自动化测试?
  4. AutoCAD学习笔记——基本操作2
  5. 录屏软件FastStone Capture汉化破解版
  6. PLC控制系统中LAN应用的介绍
  7. 空间向量绕任一向量旋转计算
  8. 最大子列和问题 c++
  9. 图论(二) 树与二分图
  10. Zebec Chain有望成为公链赛道新兴生力军,地平线计划持续进击