Sigi framework document
Introduction
Basic
Recipes
CancellationLoading/Error states handlingStateSelectorDependencies ReplacementWarning⚠️Adding new EffectModule asynchronouslyWriting tests
FAQ
基本概念
深入
常见问题

Dependencies replacement

Replace an dependencies is a common requirement when you are developing a monorepo project. For this scenario, Sigi provide InjectionProvidersContext to replace dependencies.

Dependencies replacement example

import "reflect-metadata";
import React from "react";
import { render } from "react-dom";
import { ClassProvider } from "@sigi/di";
import { useModule, 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] = useModule(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);

Warning⚠️

For performance consideration, InjectionProvidersContext should be as static as possible. For example, in most of apps in LeetCode CN, we only put the InjectionProvidersContext in AppRoot level. You should never put InjectionProvidersContext in a dynamic context:

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>
)
})

If you have the similar requirement: Use different dependencies in Component level rather than application level, you should handle the different in the EffectModule side. For example you can inject different dependencies in EffectModule, and use different dependency depend on the Payload.