Sigi framework document
Introduction
Basic
Recipes
FAQ
基本概念
深入
取消处理 Loading/Error 状态StateSelector依赖替换警告⚠️Module 异步加载测试EffectModule 异步加载
常见问题

依赖替换

在使用 monorepo 模式管理的项目中,替换依赖是非常常见的需求。对于这种场景,Sigi 提供了 InjectionProvidersContext 这个 API 来提供替换依赖的能力.

依赖替换的例子

import 'reflect-metadata'
import React from 'react'
import { render } from 'react-dom'
import { ClassProvider } from '@sigi/di'
import { useEffectModule, InjectionProvidersContext } from '@sigi/react'
import { HttpErrorClient } from './http-with-error.service'
import { HttpBetterClient } from './http-better.service'
import { AppModule } from './app.module'
const AppContainer = React.memo(({ appTitle }: { appTitle: string }) => {
const [{ list }, dispatcher] = useEffectModule(AppModule)
const loading = !list ? <div>loading</div> : null
const title = list instanceof Error ? <h1>{list.message}</h1> : <h1>{appTitle}</h1>
const listNodes = Array.isArray(list) ? list.map((value) => <li key={value}>{value}</li>) : null
return (
<div>
{title}
<button onClick={dispatcher.fetchList}>fetchList</button>
<button onClick={dispatcher.cancel}>cancel</button>
{loading}
<ul>{listNodes}</ul>
</div>
)
})
function App() {
const betterHttpProvider: ClassProvider<HttpErrorClient> = {
provide: HttpErrorClient,
useClass: HttpBetterClient,
}
return (
<>
<AppContainer appTitle="Always error" />
<InjectionProvidersContext providers={[betterHttpProvider]}>
<AppContainer appTitle="Better http client" />
</InjectionProvidersContext>
</>
)
}
const rootElement = document.getElementById('app')
render(<App />, rootElement)

警告⚠️

为了不影响性能,InjectionProvidersContext 需要尽可能的放在 静态 上下文中。比如,在 LeetCode CN 的大部分 App 中,InjectionProvidersContext 只出现在 AppRoot 这一层级的组件中。永远不要将 InjectionProvidersContext 放在动态上下文中:

const EnhancedLoggerProvider: ClassProvider<Logger> = {
provide: Logger,
useClass: EnhancedLoggerForItemDetail,
}
const Item = React.memo(({ item }: { item }: Item) => {
// very bad
return (
<InjectionProvidersContext providers={[EnhancedLoggerProvider]}>
<div key={item.id}>
<ItemDetail detail={item.data.detailObject} />
</div>
</InjectionProvidersContext>
)
})

如果你有类似的需求,即: 在组件级别而不是应用级别替换依赖,你可以在 EffectModule 中编写逻辑去处理这种需求。比如注入多个依赖到同一个 EffectModule 中,再依据不同的 Payload 使用不同的依赖。