@bem-react/di## (英语)

依赖性注射(DI) 允许您将 React 组件拆分成单独的版本,并在需要时在项目中可以舒适地切换,例如制作一个特定的捆绑.
DI软件包有助于以最小的努力解决类似的任务:
- 复数 桌面 财务报告和审定财务报表 移动 组件的版本
- 执行 实验 与共同组件并列的版本
- 在单个地方存储组件及其辅助件(类似设置和功能)
安装
npm i -S @bem-react/di
快开始
记着! 此示例使用 @ bem- react/ classname 软件包。 。 。 .
例如,对于这样的结构:
Components/
Header/
[email protected]
[email protected]
Footer/
[email protected]
[email protected]
App.tsx
首先,创建两个文件,定义App的两个版本,并使用不同的组件集: [email protected] 财务报告和审定财务报表 [email protected]把它们放在附近 App.tsx。 。 。 .
在每个App版本中([email protected] 财务报告和审定财务报表 [email protected]我们应确定应使用哪些组成部分.
这样做的三个步骤:
- 创建一个有特定编号的登记册:
const registry = new Registry({ id: cnApp() })
- 在描述性密钥下登记所有所需组件版本(说明类似组件的钥匙,在所有版本中应相同):
registry.set('Header', Header)
registry.set('Footer', Footer)
或者说
registry.fill({
Header,
Footer,
})
或者说
registry.fill({
'id-1': Header,
'id-2': Footer,
})
- 导出 App 版本及其组件登记册 :
export const AppNewVersion = withRegistry(registry)(AppCommon)
文件应该是这样的:
1. 联合国. 单位 App.tsx
import { cn } from '@bem-react/classname'
export const cnApp = cn('App')
export const registryId = cnApp()
2. 联合国. 单位 [email protected]
import { Registry, withRegistry } from '@bem-react/di'
import { App as AppCommon, registryId } from './App'
import { Footer } from './Components/Footer/Footer@desktop'
import { Header } from './Components/Header/Header@desktop'
export const registry = new Registry({ id: registryId })
registry.set('Header', Header)
registry.set('Footer', Footer)
export const AppDesktop = withRegistry(registry)(AppCommon)
3个. 单位 [email protected]
import { Registry, withRegistry } from '@bem-react/di'
import { App as AppCommon, registryId } from './App'
import { Footer } from './Components/Footer/Footer@mobile'
import { Header } from './Components/Header/Header@mobile'
export const registry = new Registry({ id: registryId })
registry.set('Header', Header)
registry.set('Footer', Footer)
export const AppMobile = withRegistry(registry)(AppCommon)
是时候用这些版本 在你的应用动态!
如果输入 App.tsx 您的依赖关系以前是静止的
import React from 'react'
import { cn } from '@bem-react/classname'
import { Header } from './Components/Header/Header'
import { Footer } from './Components/Footer/Footer'
export const App = () => (
<>
<Header />
<Footer />
</>
)
现在可以根据当前使用的注册程序注入依赖性
与 RegistryConsumer
import React from 'react'
import { cn } from '@bem-react/classname'
import { RegistryConsumer } from '@bem-react/di'
// No Header or Footer imports
const cnApp = cn('App')
export const App = () => (
<RegistryConsumer id={cnApp()}>
{({ Header, Footer }) => (
<>
<Header />
<Footer />
</>
)}
</RegistryConsumer>
)
与 useRegistry (单位:千美元)需要反应版本 16.8.0+(中文(简体) )
import React from 'react'
import { cn } from '@bem-react/classname'
import { useRegistry } from '@bem-react/di'
// No Header or Footer imports
const cnApp = cn('App')
export const App = () => {
const { Header, Footer } = useRegistry(cnApp())
return (
<>
<Header />
<Footer />
</>
)
}
这样您就可以使用您的应用程序的不同版本, 例如在您的服务器一侧有条件渲染或者创建单独的捆绑
import { AppDesktop } from './path-to/App@desktop'
import { AppMobile } from './path-to/App@mobile'
替换组件
登记册内的部件可以通过包装来取而代之(例如用于实验) withRegistry(...)(App) 与另一个登记册.
import { Registry, withRegistry } from '@bem-react/di'
import { AppDesktop, registryId } from './App@desktop'
import { HeaderExperimental } from './experiments/Components/Header/Header'
const expRegistry = new Registry({ id: registryId })
// replacing original Header with HeaderExperimental
expRegistry.set('Header', HeaderExperimental)
// AppDesktopExperimental will call App with HeaderExperimental as 'Header'
export const AppDesktopExperimental = withRegistry(expRegistry)(AppDesktop)
何时 App 从登记册提取组件 编 实际使用上面定义的所有登记册并合并。 默认情况下,更高定义的登记处将高于更低定义的登记处.
如果您想在某个时候创建注册, 而不是被覆盖, 请使用 overridable: false。 。 。 .
const boldRegistry = new Registry({ id: cnApp(), overridable: false })
扩展组件
使用方法扩展(例如用于实验)一个组件 extends(...) 登记被推翻.
import { Registry, withRegistry, withBase } from '@bem-react/di'
import { AppDesktop, registryId } from './App@desktop'
const expRegistry = new Registry({ id: registryId })
// extends original Header
expRegistry.extends('Header', (BaseHeader) => (props) => (
<div>
<BaseHeader height={200} color={red} />
</div>
))
// AppDesktopExperimental will call App with extended 'Header'
export const AppDesktopExperimental = withRegistry(expRegistry)(AppDesktop)
编 将嵌入式登记册和普通组件合并。 因此,你总是可以得到一个参考 之前组件的执行.
储存其他
编 登记处不仅可以保留组件,而且还可以保留其设置和任何其他辅助工具(类似功能).
import { useRegistry } from '@bem-react/di'
const cnHeader = cn('Header')
export const Header = (props) => {
const { theme, showNotification, prepareProps } = useRegistry(cnApp())
// one function is used to fulfill props
const { title, username } = prepareProps(props)
useEffect(() => {
// another function is used inside hook
showNotification()
})
return (
<header className={cnHeader({ theme })}>
<h1>{title}</h1>
<h2>Greetings ${username}</h2>
</header>
)
}