如何将数据从提供程序共享到函数反应



>我创建了一个共享多个实用程序函数的 NPM 库。其中之一是调用我们的端点。我已经在我的 NPM 库中包含了 Axios,但我无法全局设置Axios.create实例。

我最初以为我可以创建一个Provider并设置一个context,但是,由于我的 API 函数不在钩子内,我无法访问上下文。这是我的第一个 NPM 库,因此不熟悉最佳实践。

// Provider.ts
export default function Provider({ children, config }: ProviderProps) {
window.config = config;
return (
<ContextConfig.Provider value={config}>{children}</ContextConfig.Provider>
);
}

^ 上面,我尝试使用上下文API,设置全局变量等。

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

^上面,尝试使用全局变量window.config,然而,它是undefined。还尝试将导出转换为钩子以允许读取上下文,但是,在不安全使用钩子时出现错误。

// index.ts
import api from './api';
import Provider from './Provider';
export { api, Provider };

我现在能想到处理这个问题的唯一方法是使用本地存储,非常愿意提供建议。

干杯

你绝对应该能够将你的变量绑定到window

我认为实际发生的是,在您设置window.config之前api.ts已经启动,因此它undefined。如果将默认导出转换为函数api.ts则可以在每次调用时获取window.config的值。即;

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

这可能会降低性能,因为您将在每次调用时调用Axios.create,但是,它不应该太有影响。

除了 Axios 实例之外,您是否需要配置任何其他内容?

为什么不创建一个提供程序/上下文设置来为您处理您的 api 对象?

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

最新更新