Использование границ лени, приостановки и ошибок в React

React.js

Использование границ лени, приостановки и ошибок в React

lazy

lazyдаreactВозможности предоставленных компонентов ленивы, и в чиновке нет поддержкиlazyраньше, вreactОбычно мы используемreact-loadableЧтобы добиться возможности ленивой загрузки компонентов, но,lazyОн не поддерживает рендеринг на стороне сервера (SSR), поэтому в случае использования ssrlazyВременно недоступен

React.lazyПринимает функцию, которая вызывается внутриimport()Динамический импорт. он должен вернутьPromise,ДолженPromiseнужноresolveОдинdefalut exportизReactкомпоненты.

Как его использовать, смотрите в примере ниже

  import React, { lazy } from 'react'

  const AppTitle = lazy(() => import('./title'))

  class App extends React.Component {
    render () {
      return (
       <AppTitle></AppTitle>
      )
    }
  }

  export default App

Когда мы запустили этот код, мы обнаружили, что программа сообщила об ошибке

  Error: A React component suspended while rendering, but no fallback UI was specified.

  Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.
      in Unknown (at lazy/index.jsx:8)
      in App (at src/index.js:7)

На этот раз вам нужноreactВстроенные компонентыSuspenseSuspensefallbackатрибут, который может поддерживать передачу в разделеjsxили экземпляр компонента, например<Loading></Loading>

import React, { lazy, Suspense } from 'react'

const AppTitle = lazy(() => import('./title.jsx'))

class App extends React.Component {
    render () {
      return (
        <Suspense fallback={<div>Loading</div>}>
            <AppTitle></AppTitle>
        </Suspense>
      )
    }
}

export default App

когда мы используемlazyПосле этого мы можем открытьchromeизnetworkзатем выберитеjsДля наблюдения за инициированным запросом мы обнаружили, что на этот раз появится1.chunk.jsкоторый начинается с числаjsФайл, на самом деле каждый.jsЭто соответствует каждому из наших компонентов, когда нам нужно указать каждый упакованный асинхронный компонент.jsимя файла, нам просто нужноimport()добавлено в функцию/* webpackChunkName: "title" */В этом комментарии webpack будет автоматически использовать имя, которое мы указываем в качестве имени файла при упаковке.

import React, { lazy, Suspense } from 'react'

const AppTitle = lazy(
    () => import(/* webpackChunkName: "title" */'./title.jsx')
)

class App extends React.Component {
    render () {
      return (
        <Suspense fallback={<div>Loading</div>}>
            <AppTitle></AppTitle>
        </Suspense>
      )
    }
}
export default App

Если при асинхронной загрузке компонента загрузкаjsфайл, сетевая ошибка, невозможно загрузитьjsфайл, затемreactЭто покажет, что это

  Error: Loading chunk 3 failed.
  (error: http://192.168.4.183:3000/static/js/title.chunk.js)

很明显,Suspenseне может обработать это состояние ошибки, вreactЕсть граница ошибки(Error Boundaries)концепция, используемая для решения этой проблемы, это использованиеreactжизненный циклcomponetDidCatchметод обработки

Есть два пути, один из них — жизненный циклcomponentDidCatchДля обработки ошибок также существует статический методstatic getDerivedStateFromErrorобрабатывать ошибки,

Официальный сайт рекомендуется

Используйте static getDerivedStateFromError() для отображения альтернативного пользовательского интерфейса и используйте componentDidCatch() для печати сообщений об ошибках.

import React, { lazy, Suspense } from 'react'

const AppTitle = lazy(
    () => import(/* webpackChunkName: "title" */'./title.jsx')
)

class App extends React.Component {
    state = {
      isError: false
    }
    
    static getDerivedStateFromError(error) {
      return { isError: true };
    }
    
    componentDidCatch (err, info) {
      console.log(err, info)
    }
    
    render () {
      if (this.state.isError) {
        return (<div>error</div>)
      }
      return (
        <div>
          <Suspense fallback={<div>Loading</div>}>
            <AppTitle></AppTitle>
          </Suspense>
        </div>
      )
    }
}


export default App

Примечание: используйтеcreate-react-appПроект, созданный в среде разработки, даже если он используетсяcomponentDidCatchилиgetDerivedStateFromError, ошибка все равно будет выдаваться, вbuild

react 16ReactUI

Ссылаться на:

кодовый адрес

  1. GitHub

реагировать на другую документацию

  1. Использование контекста в React)
  2. Использование оптимизации производительности, памятки, PureComponent, shouldComponentUpdate в React

Если это поможет вам, как это точка