导入/导出模式导致的动态JSX组件名称问题

时间:2018-03-19 22:05:20

标签: javascript reactjs jsx

我正在构建一个可配置的头像组件,它根据我们想要组合的头像类型组成不同的头像特征组件。例如。盗版头像由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;

从特征中删除一个文件夹,我有一个已布置的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>
);

如果我将Features的index.js中的东西导入到Avatar的index.js(一个目录中),则会再次失败。

所以我有一些解决方法,以解决我的问题,但从Components/Avatar我可以直接导入似乎不一致,但如果我尝试从对象映射构造一个Components数组,该组件未定义。

想知道是否有人可以向我解释为什么......这是一个JSX问题,React问题还是Easy Import问题?或者我了解命名/默认导出如何工作......?

1 个答案:

答案 0 :(得分:0)

这似乎是一个简单的语法错误。您应该在每个导入上添加引号,如下所示:

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

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