React複習三

代碼分割

  • 打包
    大多數 React 應用都會使用 Webpack,Rollup 或 Browserify 這類的構建工具來打包文件。 打包是一個將文件引入併合併到一個單獨文件的過程,最終形成一個 “bundle”。 接着在頁面上引入該 bundle,整個應用即可一次性加載。

  • 代碼分割

隨着應用增長,代碼包也將隨之增長。尤其是在整合了體積巨大的第三方庫的情況下。你需要關注你代碼包中所包含的代碼,以避免因體積過大而導致加載時間過長。
需要代碼分割
代碼分割是由諸如 Webpack,Rollup 和 Browserify(factor-bundle)這類打包器支持的一項技術,能夠創建多個包並在運行時動態加載。
對你的應用進行代碼分割能夠幫助你“懶加載”當前用戶所需要的內容,能夠顯著地提高你的應用性能。儘管並沒有減少應用整體的代碼體積,但你可以避免加載用戶永遠不需要的代碼,並在初始加載的時候減少所需加載的代碼量。

  1. import()

使用之前:

import { add } from './math';
console.log(add(16, 26));

使用之後:

import("./math").then(math => {
  console.log(math.add(16, 26));
});

當 Webpack 解析到該語法時,會自動進行代碼分割。如果你使用 Create React App,該功能已開箱即用,你可以立刻使用該特性。Next.js 也已支持該特性而無需進行配置。

  1. React.lazy

React.lazy 和 Suspense 技術還不支持服務端渲染。如果你想要在使用服務端渲染的應用中使用,我們推薦 Loadable Components 這個庫。它有一個很棒的服務端渲染打包指南。

React.lazy 函數能讓你像渲染常規組件一樣處理動態引入(的組件)。

使用之前:
import OtherComponent from './OtherComponent';
使用之後:
const OtherComponent = React.lazy(() => import('./OtherComponent'));

此代碼將會在組件首次渲染時,自動導入包含 OtherComponent 組件的包。
React.lazy 接受一個函數,這個函數需要動態調用 import()。它必須返回一個 Promise,該 Promise 需要 resolve 一個 defalut export 的 React 組件。
然後應在 Suspense 組件中渲染 lazy 組件,如此使得我們可以使用在等待加載 lazy 組件時做優雅降級(如 loading 指示器等)。

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}

fallback 屬性接受任何在組件加載過程中你想展示的 React 元素。你可以將 Suspense 組件置於懶加載組件之上的任何位置。你甚至可以用一個 Suspense 組件包裹多個懶加載組件。

  • 異常捕獲邊界(Error boundaries
    如果模塊加載失敗(如網絡問題),它會觸發一個錯誤。你可以通過異常捕獲邊界(Error boundaries)技術來處理這些情況,以顯示良好的用戶體驗並管理恢復事宜。

  • 基於路由的代碼分割

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import React, { Suspense, lazy } from 'react';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path="/about" component={About}/>
      </Switch>
    </Suspense>
  </Router>
);

-命名導出(Named Exports)

Context

錯誤邊界

錯誤邊界是一種 React 組件,這種組件可以捕獲並打印發生在其子組件樹任何位置的 JavaScript 錯誤,並且,它會渲染出備用 UI,而不是渲染那些崩潰了的子組件樹。錯誤邊界在渲染期間、生命週期方法和整個組件樹的構造函數中捕獲錯誤。

注意
錯誤邊界無法捕獲以下場景中產生的錯誤:
1.事件處理(瞭解更多)
2.異步代碼(例如 setTimeout 或 requestAnimationFrame 回調函數)
3.服務端渲染
4.它自身拋出來的錯誤(並非它的子組件)

如果一個 class 組件中定義了 static getDerivedStateFromError() 或 componentDidCatch() 這兩個生命週期方法中的任意一個(或兩個)時,那麼它就變成一個錯誤邊界。當拋出錯誤後,請使用 static getDerivedStateFromError() 渲染備用 UI ,使用 componentDidCatch() 打印錯誤信息。

== 自 React 16 起,任何未被錯誤邊界捕獲的錯誤將會導致整個 React 組件樹被卸載。==

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染能夠顯示降級後的 UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 你同樣可以將錯誤日誌上報給服務器
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 你可以自定義降級後的 UI 並渲染
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

使用:

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章