在重构工作中的某些代码时,我遇到了带有嵌套React组件的循环依赖项。该功能基本上是“使用开关动态呈现嵌套在其他组件(包括它们自己)中的组件”。
我通过使用两种方法registerBlock
和HOC BlockRegistry
创建组件“注册表”解决了该问题。
// 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
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
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
。没有呼叫就可以工作的事实似乎很奇怪。
答案 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);