如何处理 React 嵌套组件循环依赖?(使用 es6 类)

How to handle React nested component circular dependency? (using es6 classes)

本文关键字:依赖 es6 循环 使用 嵌套 何处理 处理 React 组件      更新时间:2023-09-26

我正在使用 React 和 Babel (es6)。我在解决组件之间的循环依赖关系时遇到问题。

我正在构建一个菜单,我们有:

  • 项目工厂
  • 项目文件夹
  • 项目通用
  • 更多项目类型商品

ItemFactory只是根据传递的 props 返回任何其他组件。

ItemFolder需要能够重用ItemFactory,以构建嵌套的菜单项。

ItemFactory 组件,itemFactory.js(简化):


// I need ItemFolder
import ItemFolder from './itemFolder'
// import all different items too
...
function ItemFactory (props) {
  switch (props.type) {
    case 'link': return <ItemLink {...props} />
    case 'blank': return <ItemBlank {...props} />
    case 'folder': return <ItemFolder {...props} />
    default: return <ItemGeneric {...props} />
  }
}
modules.exports = ItemFactory
项目文件夹

组件,项目文件夹.js(简化):


// I need the itemFactory
import ItemFactory from './itemFactory'
...
Items = props.items.map(item => {
  return <ItemFactory {...item} />
})
module.exports = ItemFolder

如您所见,两者都需要彼此。这会导致一些循环依赖问题,我得到一个空对象。

任何帮助表示赞赏:)

在依赖关系圈中,导入的项将被解析为尚未初始化的导出绑定。如果您不立即使用它们(例如调用函数),这应该不会引起任何问题。

您的问题可能是使用 CommonJs 导出语法。以下方法应该有效:

// itemFactory.js
import ItemFolder from './itemFolder'
…
export default function ItemFactory(props) {
  switch (props.type) {
    case 'link': return <ItemLink {...props} />
    case 'blank': return <ItemBlank {...props} />
    case 'folder': return <ItemFolder {...props} />
    default: return <ItemGeneric {...props} />
  }
}

// itemFolder.js
import ItemFactory from './itemFactory'
…
export default function ItemFolder(props) {
  let items = props.items.map(item => {
    return <ItemFactory {...item} />
  })
  …
}

一种方法是将各个组件注入ItemFactory。 这样做的好处是使工厂更容易使用新类型进行扩展:

const components = {};
export function registerComponent(name, Component) {
    components[name] = Component;
};
export default function ItemFactory(props) {
    const C = components[props.type];
    return <C {...props} />;
}

// ItemFolder.js
import {registerComponent}, ItemFactory from 'itemFactory';
export default class ItemFolder {
    ...
};
registerComponent("folder", ItemFolder);