亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

characters

過去,組件內(nèi)部的JavaScript錯誤用于破壞React的內(nèi)部狀態(tài)并導(dǎo)致它在下次呈現(xiàn)時發(fā)出 隱蔽 錯誤。這些錯誤總是由應(yīng)用程序代碼中的早期錯誤引起的,但React沒有提供在組件中正常處理它們的方法,并且無法從它們中恢復(fù)。

介紹錯誤邊界

部分UI中的JavaScript錯誤不應(yīng)該破壞整個應(yīng)用程序。為了解決React用戶的這個問題,React 16引入了一個“錯誤邊界”的新概念。

錯誤邊界是React組件,可以在其子組件樹中的任何位置捕獲JavaScript錯誤,記錄這些錯誤并顯示回退UI,而不是崩潰的組件樹。錯誤邊界在渲染期間,生命周期方法以及整個樹下的構(gòu)造函數(shù)中捕獲錯誤。

注意錯誤邊界不會捕獲以下錯誤:

  • 事件處理程序(了解更多)

  • 異步代碼(例如setTimeoutrequestAnimationFrame回調(diào))

  • 服務(wù)器端渲染

  • 錯誤邊界本身(而不是它的子項)拋出的錯誤

如果一個類組件定義了一個新的生命周期方法,它將成為一個錯誤邊界componentDidCatch(error, info)

class ErrorBoundary extends React.Component {  constructor(props) {    super(props);    this.state = { hasError: false };  }  componentDidCatch(error, info) {    // Display fallback UI    this.setState({ hasError: true });    // You can also log the error to an error reporting service    logErrorToMyService(error, info);  }  render() {    if (this.state.hasError) {      // You can render any custom fallback UI      return <h1>Something went wrong.</h1>;    }    return this.props.children;  }}

然后,您可以將其用作常規(guī)組件:

<ErrorBoundary>  <MyWidget /></ErrorBoundary>

componentDidCatch()方法像JavaScript catch {}塊一樣工作,但對于組件。只有類組件可能是錯誤邊界。在實踐中,大多數(shù)時候您會想要聲明一個錯誤邊界組件并在整個應(yīng)用程序中使用它。

請注意,錯誤邊界只會在樹中的下面的組件中捕獲錯誤。錯誤邊界本身不能捕獲錯誤。如果錯誤邊界嘗試呈現(xiàn)錯誤消息失敗,則錯誤將傳播到其上方最接近的錯誤邊界。這也與catch {}塊在JavaScript中的工作方式類似。

componentDidCatch Parameters

error 是一個已經(jīng)拋出的錯誤。

info是一個componentStack關(guān)鍵的對象。在拋出錯誤期間,該屬性具有關(guān)于組件堆棧的信息。

//...componentDidCatch(error, info) {  
  /* Example stack information:
     in ComponentThatThrows (created by App)
     in ErrorBoundary (created by App)
     in div (created by App)
     in App
  */  logComponentStackToMyService(info.componentStack);}//...

現(xiàn)場演示

聲明和使用錯誤的邊界這個例子與陣營16測試版。

何處放置錯誤邊界

錯誤界限的粒度取決于您。您可能會封裝頂級路由組件以向用戶顯示“出錯了”消息,就像服務(wù)器端框架經(jīng)常處理崩潰一樣。您也可以將各個小部件封裝在錯誤邊界內(nèi),以防止其崩潰應(yīng)用程序的其余部分。

未捕獲錯誤的新行為

這一變化具有重要意義。從React 16開始,沒有被任何錯誤邊界捕獲的錯誤將導(dǎo)致整個React組件樹的卸載。

我們辯論了這個決定,但根據(jù)我們的經(jīng)驗,離開損壞的用戶界面比徹底刪除它更糟糕。例如,像Messenger這樣的產(chǎn)品將可見的UI留下,可能會導(dǎo)致某人向錯誤的人發(fā)送消息。同樣,支付應(yīng)用程序顯示錯誤的數(shù)量比不呈現(xiàn)任何內(nèi)容更糟糕。

這一變化意味著,當(dāng)您遷移到React 16時,您可能會發(fā)現(xiàn)以前未被注意到的應(yīng)用程序中現(xiàn)有的崩潰。當(dāng)出現(xiàn)錯誤時,添加錯誤邊界可以讓您提供更好的用戶體驗。

例如,F(xiàn)acebook Messenger將邊欄,信息面板,會話日志和消息輸入內(nèi)容封裝在單獨的錯誤邊界中。如果其中一個UI區(qū)域中的某個組件發(fā)生崩潰,則其余組件保持互動。

我們還鼓勵您使用JS錯誤報告服務(wù)(或自己構(gòu)建),以便您可以了解在生產(chǎn)中發(fā)生的未處理異常并對其進(jìn)行修復(fù)。

組件棧跟蹤

即使應(yīng)用程序意外吞下它們,React 16也會將所有在渲染過程中發(fā)生的錯誤打印到開發(fā)中的控制臺。除了錯誤消息和JavaScript堆棧之外,它還提供組件堆棧跟蹤?,F(xiàn)在您可以看到組件樹中確切發(fā)生故障的位置:

您還可以在組件堆棧跟蹤中看到文件名和行號。這在默認(rèn)情況下在Create React App項目中起作用:

如果您不使用Create React App,則可以手動將此插件添加到您的Babel配置中。請注意,它僅用于開發(fā),并且必須在生產(chǎn)中禁用。

注意堆棧跟蹤中顯示的組件名稱取決于Function.name屬性。如果您支持舊版瀏覽器和尚未提供此功能的設(shè)備(例如IE 11),請考慮Function.name在您的捆綁應(yīng)用程序中包含一個polyfill,例如function.name-polyfill?;蛘?,您可以displayName在所有組件上明確設(shè)置屬性。

如何嘗試/抓?。?/h2>

try/ catch很好,但它只適用于命令式代碼:

try {  showButton();} catch (error) {  // ...}

然而,反應(yīng)的組分是聲明,并指定哪些應(yīng)該呈現(xiàn):

<Button />

錯誤邊界保留了React的聲明性質(zhì),并按照您的預(yù)期行事。例如,即使樹中深處componentDidUpdatesetState某個鉤子發(fā)生錯誤,它仍然會正確傳播到最近的錯誤邊界。

如何處理事件處理程序?

錯誤邊界不會在事件處理程序中捕獲錯誤。

React不需要錯誤邊界從事件處理程序中的錯誤中恢復(fù)。與渲染方法和生命周期鉤子不同,事件處理程序在渲染過程中不會發(fā)生。所以如果他們拋出,React仍然知道要在屏幕上顯示什么。

如果您需要在事件處理程序中捕獲錯誤,請使用常規(guī)的JavaScript try/ catch語句:

class MyComponent extends React.Component {  constructor(props) {    super(props);    this.state = { error: null };  }  
  handleClick = () => {    try {      // Do something that could throw    } catch (error) {      this.setState({ error });    }  }  render() {    if (this.state.error) {      return <h1>Caught an error.</h1>    }    return <div onClick={this.handleClick}>Click Me</div>  }}

請注意,上面的示例演示了常規(guī)的JavaScript行為并且不使用錯誤邊界。

從React命名更改15

React 15在一個不同的方法名稱下包含了對錯誤邊界的非常有限的支持:unstable_handleError。此方法不再有效,您需要componentDidCatch從第16個beta版本開始將其更改為代碼。

對于這個改變,我們提供了一個codemod來自動遷移你的代碼。

Previous article: Next article: