簡體   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