@bem-react/di: Improve DX [RFC]
- Dominant language
- TypeScript
- Stars
- 450
- Forks
- 69
- PR merge metrics
- No merged PRs in 30d
Description
Можно немного ослабить связь между view и di убрав напрямую обращение в `useComponentRegistry(id)` из `@bem-react/di`, т.к. у нас все сущности хранятся в реестре, а реестр хранится рядом с компонентом, то можно делать как-то так:
**`App/registry/index.ts`**
```tsx
import { FC } from 'react'
import { createRegistry, createDepsHook } from '@bem-react/di'
type AppDeps = {
Button: FC
Input: FC
}
// Тут просто заменил конструктор на фабрику, внутри можно генерировать id,
// т.к. по факту этот id больше нигде не используется, если нужно будет
// переопределить какой-то компонент в эксперименте, можно сделать форк реестра.
export const registry = createRegistry()
// Хелпер, который внутри себя вызывает useComponentRegistry.
export const useDeps = createDepsHook(registry.id)
// Можно сделать альтертативный вариант, возвращать тапл:
export const [registry, useDeps] = createRegistry()
```
**`App/registry/desktop.tsx`**
```tsx
import { registry as emptyRegistry } from './index'
// Метод fork копирует полностью реестр, по аналогии с merge,
// но в качестве аргумента принимает хэшсет с компонентами.
export const registry = emptyRegistry.fork({
Button: () => login,
Input: () => ,
})
// Либо альтертативный вариант:
export const registry = emptyRegistry
.fork()
.fill({
Button: () => login,
Input: () => ,
})
```
**`App.tsx`**
```tsx
import { useDeps } from './registry/index'
export const App = () => {
// Тут мы ничего не знаем про реализацию DI,
// просто берем зависимости из своего реестра,
// к тому же имеем сразу вывод типов.
const { Button, Input } = useDeps()
return (
<>
)
}
```
**`App@desktop.tsx`**
```tsx
import { withRegistry } from '@bem-react/di'
import { registry } from './App/registry/desktop'
import { App as AppCommon } from './App'
export const App = withRegistry(registry)(App)
```
TODO
- [ ] Подумать как использовать с компонентами на классах
Contributor guide
Assessment
This issue has not been assessed yet.