【问题标题】:Dynamic JSX Component Name issue caused by import/export pattern由导入/导出模式引起的动态 JSX 组件名称问题
【发布时间】:2018-03-19 22:05:19
【问题描述】:

我正在构建一个可配置的 Avatar 组件,该组件根据我们想要组合的头像类型组成不同的头像特征组件。例如。海盗头像由 PegLeg 组件和 Parrot 组件组成。

最终目标是拥有一个具有所有特征的 const 映射:

const characteristicMapping = {
  pegleg: PeglegComponent, // component needed in Pirate avatar
  parrot: ParrotComponent, // component needed in Pirate avatar
  wand: WandComponent, // not used in Pirate, but used in Wizard.
};

然后基于prop(特征数组)我们组成我们需要的特征,例如

// For Pirate avatar with Pirate char. set to default value
const Avatar = ({ avatarCharacteristics = ['pegleg', 'parrot'] }) => (
  <div>
    {avatarCharacteristics.map(c => characteristicsMapping[c]).map(
      (AvatarComponent, i) => <AvatarComponent key={i} />)}
  </div>
);

我的理解是,只要 AvatarComponent 的第一个字母大写,这应该可以工作,而且可以!

但是,根据 PeglegComponentParrotComponent 的导入方式,我似乎遇到了一些问题。

我正在使用一个名为 Easy Import 的 babel 包来处理包/命名空间。

当前 PeglegComponent/ParrotComponent(sep 文件)都有 Easy Import 包名称,例如:

// @package Components/Avatar/Characteristics/PeglegComponent
export default PeglegComponent; 

// @package Components/Avatar/Characteristics/ParrotComponent
export default ParrotComponent;

从 Characteristics 向下的一个文件夹,我有一个 index.js 文件,它的布局:

// @package Components/Avatar

import PeglegComponent from 'Components/Avatar/Characteristics/PeglegComponent';
import ParrotComponent from 'Components/Avatar/Characteristics/ParrotComponent';

export default {};
export { PeglegComponent, ParrotComponent };

因此,组成 Avatar 组件中的导入看起来像这样:

import { PeglegComponent, ParrotComponent } from 'Components/Avatar';

const characteristicsMapping = {
  pegleg: PeglegComponent, // component needed for Pirate Avatar
  parrot: ParrotComponent, // component needed for Pirate Avatar
};

// For Pirate avatar with Pirate char. set to default value
const Avatar = ({ avatarCharacteristics = ['pegleg', 'parrot'] }) => (
  <div>
    {avatarCharacteristics.map(c => characteristicsMapping[c]).map(
      (AvatarComponent, i) => <AvatarComponent key={i} />)}
  </div>
);

在这种情况下,我得到了错误:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports

更重要的是,如果我 console.log characteristicsMapping 我得到 {pegleg: undefined, parrot: undefined}

因此,无论出于何种原因,导入都失败了。奇怪的是,这似乎只是一个动态组件名称问题。例如。如果我这样做,它会起作用,并且导入完全相同:

import { PeglegComponent, ParrotComponent } from 'Components/Avatar';

// For Pirate avatar with Pirate char. set to default value
const Avatar = () => (
  <div>
    <PeglegComponent />
    <ParrotComponent />
  </div>
);

起初我以为我根本无法动态组件名称,但该功能消失了,但后来我发现这可以工作。

import PeglegComponent from 'Components/Avatar/Characteristics/PeglegComponent';
import ParrotComponent from 'Components/Avatar/Characteristics/ParrotComponent';

const characteristicsMapping = {
  pegleg: PeglegComponent, // component needed for Pirate Avatar
  parrot: ParrotComponent, // component needed for Pirate Avatar
};

// For Pirate avatar with Pirate char. set to default value
const Avatar = ({ avatarCharacteristics = ['pegleg', 'parrot'] }) => (
  <div>
    {avatarCharacteristics.map(c => characteristicsMapping[c]).map(
      (AvatarComponent, i) => <AvatarComponent key={i} />)}
  </div>
);

另外,如果我在与 PeglegComponent/ParrotComponent 相同的文件夹中有一个 index.js 文件,然后从那里导入它就可以工作。

Components/Avatar/Characteristics 中有一个 index.js,其中包含:

// @package Components/Avatar/Characteristics

import PeglegComponent from 'Components/Avatar/Characteristics/PeglegComponent';
import ParrotComponent from 'Components/Avatar/Characteristics/ParrotComponent';

export default {};
export { PeglegComponent, ParrotComponent };

然后这个工作:

import { PeglegComponent, ParrotComponent } from 'Components/Avatar/Characteristics';

const characteristicsMapping = {
  pegleg: PeglegComponent, // component needed for Pirate avatar
  parrot: ParrotComponent, // component needed for Parrot avatar
};

// For Pirate avatar with Pirate char. set to default value
const Avatar = ({ avatarCharacteristics = ['pegleg', 'parrot'] }) => (
  <div>
    {avatarCharacteristics.map(c => characteristicsMapping[c]).map(
      (AvatarComponent, i) => <AvatarComponent key={i} />)}
  </div>
);

如果我将特性的 index.js 中的内容导入 Avatar 的 index.js(上一个目录),则会再次失败。

所以我有一些变通方法来解决我的问题,但是从 Components/Avatar 导入我可以直接这样做似乎不一致,但是如果我尝试从对象映射构造一个组件数组,那么组件出现未定义。

想看看是否有人可以向我解释为什么.. 这是 JSX 问题、React 问题还是 Easy Import 问题?或者我对命名/默认导出如何工作的理解......?

【问题讨论】:

    标签: javascript reactjs jsx


    【解决方案1】:

    这似乎是一个简单的语法错误。您应该像这样在每次导入时添加引号:

    import PeglegComponent from './Components/Avatar/Characteristics/PeglegComponent';
    

    这是文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

    【讨论】:

    • 啊,我正在使用 Easy Import,它允许您定义 // @package Components/Avatar/Characteristics/PeglegComponent 然后在没有 . /
    • 我相信你仍然需要引号。 “”
    • 如果您编辑原始帖子,这将不再是一个有效的问题。如果它解决了问题,请接受这个答案并保持原样。
    • 它不能解决问题。当前的想法是 Easy Import 的错误。不知道编辑礼仪,但在我看来,用单引号包围导入路径不会使问题无效,只会修复一个错字。我的原始代码确实有引号,它们在编写问题时丢失了,mea culpa。
    猜你喜欢
    • 1970-01-01
    • 2015-05-04
    • 2015-07-04
    • 2019-12-05
    • 1970-01-01
    相关资源
    最近更新 更多