Webpack 导入代码分割渲染 <undefined>

3

我正在尝试进行基于组件的代码拆分。使用的是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;
  };

组件在 Dev 工具调试器中正常显示,但呈现为 <undefined></undefined>
有人能帮忙吗?

好的,这里一切都很好。 但可能的问题是renderDecisions在哪里以及如何使用?它是在一个单独的类中(例如decisionLoader),还是直接在另一个组件内部使用? 我猜更新时出了些问题。 - Moji Izadmehr
@MojtabaIzadmehr,“renderDecisions”方法是从“render() -> renderLayout()”方法调用堆栈中调用的。据我在Dev工具中所见,renderDecisions返回一个VNode。仍然不清楚正在发生什么。 - amit
我猜问题在于您从未指示组件已成功导入,并重新渲染组件(这可能是原因,您可以在devTools中看到其值但没有渲染,但是如果组件仍未导入而不是<undefined>,则应该会遇到错误)。尝试一些简单的方法并检查是否有任何更改。在loadDecisions中,在返回之前,使用this.forceUpdate()强制更新组件。 - Moji Izadmehr
可能是React中的一个bug,请在那里报告。因为它不应该返回<undefined>。React调用函数组件,并在确定函数类型后创建类的实例。因此,如果组件本身不是组件,则应返回错误。 - Moji Izadmehr
我注意到的一件事是,无论我给组件提供什么路径进行导入,它总是导入该块。即使路径是错误的。这就是事情开始变得混乱的地方。 - amit
即使使用相对路径名,也可以吗? - Moji Izadmehr
3个回答

0
你确定你一开始没有返回一个 Promise,然后将其传递给 JSX 吗?这会导致 undefined。
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;
};

0

你的路径名应该以./开头,这样相对模块的动态导入才能正常工作。

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


你能在 https://codesandbox.io/s/new 上创建一个最小可复现的示例吗?这将有助于我们更好地调试问题。 - Ganapati V S

0
从 React 文档 中:

你不能使用普通表达式作为 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;
  };

你提到的听起来是正确的。但它仍然没有生效。我仍然看到<undefined></undefined> - amit
请检查在 'src/components/decisions' 中是否有 export default ... - Mohamed Ramrami
我在类中设置了“export default”。 - amit
你说的不对,你其实可以直接使用类字段作为组件,<this.state.TmplDecisions> 可以正常工作,试一下吧 :) - Moji Izadmehr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接