国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

characters

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

介紹錯(cuò)誤邊界

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

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

注意錯(cuò)誤邊界不會(huì)捕獲以下錯(cuò)誤:

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

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

  • 服務(wù)器端渲染

  • 錯(cuò)誤邊界本身(而不是它的子項(xiàng))拋出的錯(cuò)誤

如果一個(gè)類組件定義了一個(gè)新的生命周期方法,它將成為一個(gè)錯(cuò)誤邊界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 {}塊一樣工作,但對(duì)于組件。只有類組件可能是錯(cuò)誤邊界。在實(shí)踐中,大多數(shù)時(shí)候您會(huì)想要聲明一個(gè)錯(cuò)誤邊界組件并在整個(gè)應(yīng)用程序中使用它。

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

componentDidCatch Parameters

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

info是一個(gè)componentStack關(guān)鍵的對(duì)象。在拋出錯(cuò)誤期間,該屬性具有關(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)場演示

聲明和使用錯(cuò)誤的邊界這個(gè)例子與陣營16測(cè)試版。

何處放置錯(cuò)誤邊界

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

未捕獲錯(cuò)誤的新行為

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

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

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

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

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

組件棧跟蹤

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

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

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

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

如何嘗試/抓住?

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

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

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

<Button />

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

如何處理事件處理程序?

錯(cuò)誤邊界不會(huì)在事件處理程序中捕獲錯(cuò)誤。

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

如果您需要在事件處理程序中捕獲錯(cuò)誤,請(qǐng)使用常規(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>  }}

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

從React命名更改15

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

對(duì)于這個(gè)改變,我們提供了一個(gè)codemod來自動(dòng)遷移你的代碼。

Previous article: Next article: