了解嵌套React组件中的模块范围

时间:2019-07-24 01:49:45

标签: javascript reactjs

在重构工作中的某些代码时,我遇到了带有嵌套React组件的循环依赖项。该功能基本上是“使用开关动态呈现嵌套在其他组件(包括它们自己)中的组件”。

我通过使用两种方法registerBlock和HOC BlockRegistry创建组件“注册表”解决了该问题。

src / BlocksNode.js

// src/BlocksNode.js - accepts and renders a block passed from the API

import BlockRegistry, { registerBlock } from './BlockRegister'
import ComponentOne from './ComponentOne'
import ComponentTwo from './ComponentTwo'

// accepts a name and a component
registerBlock('componentOne', ComponentOne)
registerBlock('componentTwo', ComponentTwo)

// reads a block from the API and uses the type passed from props
const BlocksNode = (props) => {
const { type, blocks } = props
return <BlockRegistry type={type} blocks={blocks} />
}
export default BlocksNode

src / BlockRegister.js

const components = {}

export function registerBlock(name, Component) {
  components[name] = Component
}

const BlockRegistry = (props) => {
  const { type, ...rest } = props
  const Component = components[type]
  return <Component {...rest} />
}

export default BlockRegistry

src / ComponentOne.js

import BlockRegistry from './BlockRegister'

function ComponentOne(props) {
  const { blocks } = props
  return (
    <div>
      {blocks.map((block) => {
        const { type, blocks } = block
        return <BlockRegistry type={type} blocks={blocks} />
      })}
    </div>
  )
}

export default ComponentOne

ComponentOne.js可以传递任意数量的其他块,包括ComponentTwo.js或它本身。我简化了一些逻辑,但是要点在这里。

此解决方案效果很好。但是我不明白它是如何工作的。从逻辑上讲,我希望嵌套组件的作用域包括顶级已注册组件。如何处理范围,以使嵌套的组件在没有对registerBlock()的新的嵌套调用的情况下工作?

例如,<BlockRegistry />中的ComponentOne.js如何找到block.type === 'componentTwo'的匹配项?我希望需要重新注册它,即。通过在registerBlock('componentTwo', ComponentTwo)内执行ComponentOne.js。没有呼叫就可以工作的事实似乎很奇怪。

1 个答案:

答案 0 :(得分:0)

  

例如,在ComponentOne.js中如何找到block.type ==='componentTwo'的匹配项?

因为将类型传递给BlockRegistry

<BlockRegistry type={type} blocks={blocks} />

,在BlockRegistry中,您将获得基于该类型的组件

const Component = components[type]

  

我希望需要在嵌套级别注册所有可用组件,即。通过在ComponentOne.js中执行registerBlock('componentTwo',ComponentTwo)

您只需要在范围内存储components。例如

BlockRegister.js


export default function register(supportedComponents) {
  const BlockRegistry = (props) => {
    const { type, ...rest } = props;
    const Component = supportedComponents[type];
    return <Component {...rest} />
  };
  return BlockRegistry;
}

BlocksNode.js

const supportedComponent = {
  'componentOne': ComponentOne,
  'componentTwo': ComponentTwo,
}

const BlockRegistry = register(supportedComponent);