Creé una biblioteca NPM que comparte múltiples funciones útiles. Uno de los cuales es llamar a nuestros puntos finales. Incluí Axios en mi biblioteca NPM, pero no puedo configurar la instancia Axios.create globalmente.
Inicialmente pensé que podía crear un Provider y establecer un context , sin embargo, como mi función API no está dentro de un enlace, no puedo acceder al contexto. Esta es mi primera biblioteca de NPM, por lo que no estoy familiarizada con las mejores prácticas.
// Provider.ts
export default function Provider({ children, config }: ProviderProps) {
window.config = config;
return (
<ContextConfig.Provider value={config}>{children}</ContextConfig.Provider>
);
}
^ Arriba, intenté usar la API de contexto, establecer una variable global, etc.
// api.ts
import Axios, { AxiosInstance, AxiosPromise, Cancel } from 'axios';
const axiosInstance = Axios.create(window.config);
const api = (axios: AxiosInstance) => ({
get: <T>(url: string, config: ApiRequestConfig = {}) =>
withLogger<T>(withAbort<T>(axios.get)(url, config)),
});
export default api(axiosInstance)
^ Arriba, intenté usar la variable global window.config , sin embargo, no está undefined . También intenté convertir la exportación en un gancho para permitir leer el contexto, sin embargo, obtuve errores sobre el uso inseguro de los ganchos.
// index.ts
import api from './api';
import Provider from './Provider';
export { api, Provider };
La única forma en que puedo pensar en manejar esto ahora es usando Almacenamiento local, muy abierto a aconsejar.
Salud
Absolutamente debería poder vincular su variable a la window .
Lo que creo que realmente sucedió es que api.ts se inició antes de configurar window.config , por lo que no está undefined . Si convirtió la exportación predeterminada de api.ts en una función, podrá obtener el valor de window.config en cada llamada. ES DECIR;
// api.ts
import Axios, { AxiosInstance, AxiosPromise, Cancel } from 'axios';
const api = (axios: AxiosInstance) => ({
get: <T>(url: string, config: ApiRequestConfig = {}) =>
withLogger<T>(withAbort<T>(axios.get)(url, config)),
});
export default () => {
const axiosInstance = Axios.create(window.config);
return api(axiosInstance)
}
Esto puede tener un poco menos de rendimiento ya que llamará a Axios.create en cada llamada, sin embargo, no debería ser demasiado impactante.
¿Necesita la configuración para algo que no sea su instancia de Axios?
¿Por qué no simplemente crear una configuración de Proveedor/Contexto que maneje su objeto API por usted?
// Create a context for the api
const ApiContext = createContext({});
// Create a Provider component.
const ApiProvider = ({ config }) => {
// recreate the api every time the provided configuration changes.
const api = useMemo(() => {
// create axios instance using the provided config.
const axiosInstance = Axios.create(config);
// create API object
return {
get: <T,>(url: string, apiConfig: ApiRequestConfig = {}) => withLogger<T>(withAbort<T>(axiosInstance.get)(url, apiConfig))
};
}, [config] /* dependency array - determines when api will be recomputed */)
return (
<ApiContext.Provider value={api}>
{children}
</ApiContext.Provider>
);
};
const useApi = () => {
// retrieve configured API from context.
const api = useContext(ApiContext);
return api;
}
// Example component to show how to retrieve api for use.
const Example = () => {
// retrieve configured API from context.
const api = useContext(ApiContext);
//OR
const api = useApi();
// use api here
return (
<div>
Content goes here
</div>
)
}
// App component to show providing config for API.
const App = () => {
// Create config (should only update reference when values need to change)
const config = useMemo(() => ({
// add config here
}), []);
return (
// pass config to API Provider.
<ApiProvider config={config}>
<Example />
</ApiProvider>
)
}