【问题标题】:React Code Splitting in React.createElement()React.createElement() 中的 React 代码拆分
【发布时间】:2021-06-30 18:07:47
【问题描述】:

我有页面或大型组件需要在主页加载后呈现。我懒惰地加载了它们,但是当我在 createElement() 中使用时出现错误:

LazyExoticComponent | LazyExoticComponent 不能分配给类型为“字符串”的参数 |函数组件 | ComponentClass'

我测试过的内容:

import Page2 from "./Page2";
import Page3 from "./Page3";
const pages = [Page2, Page3];

//in any method in the react component
let s = [Page2];
let ss = [Page2, Page3];
let sss = pages[0];
let r = React.createElement(s[0]); //this works
let rr = React.createElement(ss[0]); //does not work
let rrr = React.createElement(sss); //does not work

使用最新版本的 Typescript、React、React-Scripts 似乎没有任何影响。

Typescript ^3.9.9,React ^16.14.0,React-Scripts ^2.1.8,“@types/react”:“^17.0.0”,“react-dom”:“^16.13.1”,没有@types/react-dom

【问题讨论】:

  • 既然现在可以使用 JSX,为什么还要使用 createElement?
  • 该示例被缩短以显示 step 变量发生的情况的大图。在我的实际程序中,step 变量在添加到 render() 的返回之前存储在 state 中。我不确定是否有好处,但这就是我从前一组获得项目的方式。
  • 错误是:LazyExoticComponent | LazyExoticComponent | ... 不能分配给“字符串”类型的参数。编辑帖子以更准确地描述情况。
  • 我了解您在下面的帖子如何以及为什么有效 +1。我尝试了一个小时,但无法在沙盒中复制。更新了帖子,希望能删掉不必要的部分。
  • 好像是这样。我不知道为什么。

标签: reactjs typescript lazy-loading react-lazy-load


【解决方案1】:

这个特殊的问题与 React.Component 类型的泛型有关。如果使用数组,每个元素页面的 React.Component 'signature' 必须相同,否则会抛出此错误。例如:

export default class Page2 extends React.Component {...}
export default class Page3 extends React.Component {...}

//in main file
const Page2 = lazy( ()=>import('./Page2') );
const Page3 = lazy( ()=>import('./Page3') );
const pages = [Page2, Page3];
...
let page = React.createElement(pages[1]);

这将起作用,因为 Page2 和 Page3 的“签名”是相同的。即,它们是 .

export default class Page2 extends React.Component<IPage2Props, IPage2State>
export default class Page3 extends React.Component<IPage3Props, IPage3State>

另一方面,这些将不起作用,并且是导致我发布的问题的原因。即使 IPage3Props 和 IPage2Props 在 interface/type 中的内容相同,它 TS 仍然不会理解。

据我所知,这个问题与环境或 TS 的版本或使用的 React 没有任何关系。

显而易见的解决方案是使“签名”相同。这可能不切实际,我不确定还有什么办法可以解决这个问题。

【讨论】:

  • 如果您丢失了原始帐户的电子邮件地址,您可以标记您的帖子以引起版主注意,或单击页面底部的“联系我们”按钮。无论哪种情况,请清楚说明问题,以便合并您的帐户。
  • 是的。它与打字有关。 Lazy 和 Suspense 会正常工作。
【解决方案2】:

您可以简单地将lazySuspense 与后备内容一起使用。

然后应该在 Suspense 组件中呈现惰性组件,这允许我们在等待惰性组件加载时显示一些备用内容(例如加载指示器)。

一个例子:

import React, { Component, createElement, lazy, Suspense } from "react";

const Page2 = lazy(() => import("./Page2"));
const Page3 = lazy(() => import("./Page3"));

const pages = [Page2, Page3];

class App extends Component {

  render() {
    let s = [Page2];
    let ss = [Page2, Page3];
    let sss = pages[0];
    let r = createElement(s[0]);
    let rr = createElement(ss[0]);
    let rrr = createElement(sss);
    return (
      <>
        <h2>App</h2>
        <Suspense fallback="loading..."> {/* <== using the Suspense /*}
          {r} {rr} {rrr}
        </Suspense>
      </>
    );
  }
}

这里是CodeSandbox

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-26
    • 2020-01-10
    • 2017-11-11
    • 2017-06-13
    • 2017-06-13
    • 2017-09-30
    • 1970-01-01
    • 2020-03-03
    相关资源
    最近更新 更多