【问题标题】:Webpack Import Code Splitting rendering <undefined>Webpack 导入代码拆分渲染 <undefined>
【发布时间】:2019-01-17 22:44:19
【问题描述】:

我正在尝试进行基于组件的代码拆分。 Webpack 3.

    loadDecisions = async () => {
    if (!this.TmplDecisions) {
      this.TmplDecisions = await import(
        /* webpackChunkName: "chunk-templates-decisions" */ 'src/components/decisions'
      );
    }

    return this.TmplDecisions;
  }

  renderDecisions () {
    if (this.TmplDecisions && this.TmplDecisions.default) {
      return <this.TmplDecisions.default 
        {...this.props} 
        logOpenEvent={this.logTagOpenEvent}
      />;
    } else return null;
  };

该组件在开发工具调试器中显示良好,但呈现为 &lt;undefined&gt;&lt;/undefined&gt;

有人可以帮忙吗?

【问题讨论】:

  • 嗯,这里一切都很好。但可能的一点是renderDecisions 在哪里以及如何使用?它是在一个单独的类中(类似于decisionLoader,还是您直接在另一个组件中使用它?我猜是更新有问题。
  • @MojtabaIzadmehr 正在从render() -&gt; renderLayout() 方法调用堆栈调用renderDecisions 方法。据我在开发工具中看到的,renderDecisions 返回一个VNode。仍然不知道发生了什么。
  • 我想问题是你从来没有指出组件已成功导入,并重新渲染组件(这可能是你可以在 devTools 中看到它的值但没有渲染的原因,但是,如果组件仍未导入而不是 ),您应该会遇到错误。尝试一些简单的事情并检查它是否改变了任何东西。在loadDecisions,就在返回之前,用this.forceUpdate()强制更新组件。
  • 这可能是反应中的一个错误,也请在那里报告。因为在任何情况下它都不应该返回 。 React 调用函数式组件,并在确定函数的类型后创建类的实例。所以如果组件本身不是一个组件,它应该返回一个错误。
  • 我注意到的一件事是,无论我为要导入的组件提供什么路径,它总是会导入块。即使路径是错误的。这就是事情开始变得混乱的地方。

标签: javascript reactjs webpack preact


【解决方案1】:

您的路径名应以 ./ 开头,以便动态导入相关模块。

例如:/* webpackChunkName: "chunk-templates-decisions" */ './src/components/decisions.js'(注意 ./ 这里,否则 webpack 将 src 视为 npm 模块)。

【讨论】:

  • 你能在codesandbox.io/s/new 上创建最小复制吗?它应该可以帮助我们更好地调试问题。
【解决方案2】:

来自 React docs

您不能使用通用表达式作为 React 元素类型。如果您确实想使用通用表达式来指示元素的类型,只需先将其分配给大写变量即可。

所以先尝试将类型分配给大写的变量。

还将TmplDecisions 添加到状态(或使用标志,例如tmplDecisionsLoaded),以便在加载TmplDecisions 后React 重新渲染。

  loadDecisions = async () => {
    if (!this.state.TmplDecisions) {
      const TmplDecisions = await import(
        /* webpackChunkName: "chunk-templates-decisions" */ 'src/components/decisions'
      );

      this.setState({ TmplDecisions });
      return TmplDecisions;
    } else {
      return this.state.TmplDecisions;
    } 
  }

  renderDecisions () {
    if (this.state.TmplDecisions && this.state.TmplDecisions.default) {
      const MyComponent = this.state.TmplDecisions.default;
      return <MyComponent
        {...this.props} 
        logOpenEvent={this.logTagOpenEvent}
      />;
    } else return null;
  };

【讨论】:

  • 你提到的听起来不错。但它仍然无法正常工作。我仍然看到&lt;undefined&gt;&lt;/undefined&gt;
  • 检查export default ...中是否有'src/components/decisions'
  • 我在课堂上设置了导出默认值。
  • 你说的不对,其实你可以简单的用一个class字段作为组件,就可以了,看看吧:)
【解决方案3】:

你确定你没有首先返回一个后来传递给 JSX 的承诺吗? 那会让你不确定。

componentDidMount() {
  const TmplDecisions = this.TmplDecisions && this.TmplDecisions.default;
  if (TmplDecisions instanceof Promise) {
    TmplDecisions.then((RealTmplDecisions) => this.setState({ TmplDecisions: RealTmplDecisions}));
    return;
  }
  if (TmplDecisions instanceof Function) {
    this.setState({
      TmplDecisions
    });
    return;
  }
}

// On shouldComponentUpdate you need to check 
// if state.TmplDecisions !== undefined 
// among whatever else you are doing there

renderDecisions () {
  if (this.state.TmplDecisions) {
    return <this.state.TmplDecisions 
      {...this.props} 
      logOpenEvent={this.logTagOpenEvent}
    />;
  } else return null;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 2023-03-12
    • 2016-02-24
    • 2019-12-26
    • 2017-10-03
    • 1970-01-01
    • 2018-10-08
    • 2017-12-14
    相关资源
    最近更新 更多