繁体   English   中英

如何从 Provider 共享数据到 function react

[英]How to share data from Provider to function react

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

我最初以为我可以创建一个Provider并设置一个context ,但是,由于我的 API function 不在钩子内,我无法访问上下文。 这是我的第一个 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

我认为实际发生的是api.ts在您设置window.config之前已经启动,因此它是undefined的。 如果您将api.ts默认导出转换为 function,您将能够在每次调用时获得window.config的值。 IE;

// 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 object 的提供者/上下文设置?

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM