【问题标题】:React.lazy not loading any componentsReact.lazy 不加载任何组件
【发布时间】:2020-06-06 03:03:47
【问题描述】:

我正在尝试在 React 应用程序中实现一些代码拆分。在这种情况下,这并不是绝对必要的,因为它是一个相当小的应用程序,但我想我会先在低风险环境中尝试这种技术,然后再在更大的项目中实施它。

我的代码有效:

import React from 'react'
import { useUser } from './context/userContext'
import Layout from './components/layout'
import Routes from './components/routes'
import LandingScreen from './components/authApp/LandingScreen'

const App = () => {
  const user = useUser()

  return (
    <>
      {user ? (
        <Layout>
          <Routes />
        </Layout>
      ) : (
        <LandingScreen />
      )}
    </>
  )
}

export default App

如果我尝试更改任何组件以使用 React.lazy,例如

const LandingScreen = React.lazy(() => import('./components/authApp/landingScreen'))

我的应用编译正常,但浏览器中没有呈现任何组件,我收到此错误:

index.js:1 The above error occurred in one of your React components:
    in Unknown (at App.js:26)
    in App (at src/index.js:14)
    in UserProvider (at appProvider.js:7)
    in AuthProvider (at appProvider.js:6)
    in AppProviders (at src/index.js:13)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/docs/error-boundaries.html to learn more about error boundaries.

如果我在这里做错了什么,我将不胜感激。 LandingScreen 组件只是渲染了一些 div 和我的登录组件,但是即使它只是渲染单个 div 也会出现同样的错误。'

编辑:将延迟加载的组件包装在 Suspense 组件中修复它。文档似乎表明 Suspense 组件是可选的,但也许不是?任何知道更多并且可以加入的人,将不胜感激。

【问题讨论】:

  • 导入路径不错,是的,它确实默认导出组件。
  • 感谢您对文档中的措辞提供反馈。我提出了更改措辞并可能开启对话的拉取请求:github.com/reactjs/reactjs.org/pull/2768
  • @Adam 很好的反馈,谢谢。我在 PR 中包含了一条关于可能更改措辞的说明,以明确其中一个或另一个是必需的。我将推送一个新的提交,并添加一些额外的措辞以使其更清晰。
  • 我已将 PR 中的措辞更改为“必须在 Suspense 组件或替代组件中呈现惰性组件”。如果您有更清晰的描述方式的想法,我愿意进行对话。
  • @JamieDixon 不,我认为可行。感谢您打开 PR,我认为它可以帮助像我这样的人。

标签: reactjs


【解决方案1】:

lazy 组件应该Suspense 的后代,如果您使用Suspense,那么您需要提供fallback: p>

All right here in the docs

const App = () => {
  const user = useUser()

  return (
    <Suspense fallback={<></>}>
      {user ? (
        <Layout>
          <Routes />
        </Layout>
      ) : (
        <LandingScreen />
      )}
    </Suspense>
  )
}

注意:你没有使用Suspense,但如果你没有,那么你基本上必须用你自己的ErrorBoundary重新发明它,所以更容易使用它。

悬念陷阱

如果Suspense 下的任何组件在渲染时挂起(例如lazy),那么直到最近的 Suspense 的整个组件树都会在组件准备好时卸载并重新挂载。这可能是个大问题。

Suspense 实际上在做什么?

React 一直在抛出这个想法,组件可以throw 一个 Promise -throw 在这里非常重要,它不能返回一个Promise,它必须 throw它 - 表示它是“异步的”。如果最近的ErrorBoundarySuspense 是)捕获了Promise,那么它显示它是fallback 属性。当它捕获的 Promise 解析时,它会呈现为 children - 当您考虑它实际在做什么时,这非常简单。

我说它一直在玩弄这个想法,因为即使他们已经为Suspense 实现了它,他们也将它视为用于数据加载的 API,事实上,人们已经证明你可以使用它现在就这样(现在找不到链接,但它超级酷)。

The API for data fetching is expected to be formalized sometime in the near future.

【讨论】:

  • 您能否详细说明 Suspense 是什么/做什么?
  • 谢谢,我确实解决了这个问题(请参阅我的编辑),但是文档表明“应该”包含在悬念中,这表明它是可选的,不是必需的。也许只是一个应该修正的轻微措辞。
  • 我假设你在渲染服务器端时不能使用 Suspense?它的默认反应是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2020-10-15
  • 2019-06-17
  • 1970-01-01
  • 2016-10-04
相关资源
最近更新 更多