Use apiClient factory to dynamically resolved different values at runtime

This commit is contained in:
Alejandro Celaya
2023-07-26 20:04:50 +02:00
parent 3a0cea1268
commit d49da185d3
33 changed files with 146 additions and 80 deletions

View File

@@ -5,7 +5,6 @@ import { useEffect, useRef, useState } from 'react';
import { Provider } from 'react-redux';
import type { SemVer } from '../src/utils/helpers/version';
import type { ShlinkApiClient } from './api-contract';
import { setUpStore } from './container/store';
import { FeaturesProvider, useFeatures } from './utils/features';
import { RoutesPrefixProvider } from './utils/routesPrefix';
import type { Settings } from './utils/settings';
@@ -18,6 +17,11 @@ type ShlinkWebComponentProps = {
apiClient: ShlinkApiClient;
};
// FIXME
// This allows to track the reference to be resolved by the container, but it's hacky and relies on not more than one
// ShlinkWebComponent rendered at the same time
let apiClientRef: ShlinkApiClient;
export const createShlinkWebComponent = (
bottle: Bottle,
): FC<ShlinkWebComponentProps> => ({ routesPrefix = '', serverVersion, settings, apiClient }) => {
@@ -25,15 +29,21 @@ export const createShlinkWebComponent = (
const mainContent = useRef<ReactNode>();
const [theStore, setStore] = useState<Store | undefined>();
// Set client on every re-render
apiClientRef = apiClient;
useEffect(() => {
bottle.constant('apiClient', apiClient);
bottle.value('apiClientFactory', () => apiClientRef);
// It's important to not try to resolve services before the API client has been registered, as many other services
// depend on it
const { container } = bottle;
const { Main } = container;
const { Main, store, loadMercureInfo } = container;
mainContent.current = <Main />;
setStore(setUpStore(container));
setStore(store);
// Load mercure info
store.dispatch(loadMercureInfo());
}, []);
return !theStore ? <></> : (