簡體   English   中英

調用 javascript 函數時使用反應鈎子的正確方法是什么?

[英]What is proper way to use react hooks when calling javascript functions?

我只是在學習鈎子如何在更大的應用程序中工作。 我試圖弄清楚這里的正確模式是什么。 我通常將我的 api 調用包裝在他們自己的文件中。 例如,我可能會調用文件 Customers.Api.js 中的客戶列表:

import axios from 'axios';

const client = await getApiClient();
const reply = await client.get(`${baseUrl}/customers`);
return reply;

getApiClient() 的工作是獲取已添加授權 header 的 axios 實例。 我從 Auth0 得到這個,但這部分並不重要,因為我真的在這里尋找模式而不是 Auth0 的細節,可能是任何鈎子:

// Engine.Api.js
// Inside an axios interceptor called from getApiClient()
const { getAccessTokenSilently } = useAuth0(); // <-- this is not allowed in a plain js func

const token = await getAccessTokenSilently({}); 
request.headers.Authorization = `Bearer ${token}`;
...
return request

由於我的令牌來自鈎子,我應該如何設置它?

我不想每次都這樣做:

const { getAccessTokenSilently } = useAuth0();
const token = await getAccessTokenSilently({});
const client = await getApiClient();
const reply = await client.get(`${baseUrl}/customers`,{
  headers: `Authorization: Bearer ${token}`,
})

我更喜歡某種方式來做到這一點(或類似的東西):

const customers = await getCustomers();

getCustomers() 將存在於 Customers.Api.js 中,並且會具有以下內容:

const client = await getApiClient(); // <-- this would use interceptor to add bearer
return await client.get(`${baseUrl}/customers`);

最終解決方案

在看了安德烈要說的話之后,我終於到達了我需要去的地方。 這是我最終做的事情:

const axiosClient = axios.create();

export function useApiClient() {
  const { getAccessTokenSilently, isLoading } = useAuth0();
  const [state, setState] = useState({
    loading: true,
    authHeader: null,
    token: '',
    client: null,
  });

  useEffect(() => {
    (async () => {
      if (!isLoading) {
        if (state.token === '') {
          const apiToken = await getAccessTokenSilently({
            audience: 'https://example.com/',
            scope: 'read:current_user',
          });
          setState({ ...state, authHeader: { Authorization: `Bearer ${apiToken}` }, token: apiToken });
    }

    if (state.token && !state.client && state.loading) {
      setState({ loading: false, client: axiosClient });
    }
  }
})();
}, [getAccessTokenSilently, state, isLoading]);
  return { ...state };

}

之后我也對其進行了很多修改,因為這並不是我真正的用例,但它確定了我不理解的內容。 謝謝安德烈!!!!

這通常通過創建另一個將所有必要邏輯包裝在內的鈎子來解決。

Auth0 文檔實際上有一個示例: https://github.com/auth0/auth0-react/blob/master/EXAMPLES.md#4-create-a-useapi-hook-for-accessing-protected-apis-with -一個訪問令牌

在你的情況下,你可以這樣做:

客戶.Api.js

export function useCustomers() {
  const [state, setState] = useState({ customers: [] });
  const { getAccessTokenSilently } = useAuth0();
  useEffect(() => {
    (async () => {
      const token = await getAccessTokenSilently({});
      const client = await getApiClient();
      const reply = await client.get(`${baseUrl}/customers`,{
        headers: `Authorization: Bearer ${token}`,
      })
      setState({ customers: reply.data });
    })
  });
  return state;
}

(未經測試,可能實際上不起作用,但希望這個想法很清楚)

在一個組件中

const { customers } = useCustomers();

下一步是將useCustomers鈎子推廣到像useApi和內部useCustomers簡單地調用useApi

此外,您可能會發現官方的 Building Your Own Hook文檔很有幫助,它解釋了最常見的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM