我只是在学习 Hook 如何在较大的应用程序中工作。我想弄清楚这里的正确模式是什么。我通常将我的 api 调用包装在它们自己的文件中。例如,我可能会调用以获取文件 Customers.Api.js 中的客户列表:
import axios from 'axios';
const client = await getApiClient();
const reply = await client.get(`${baseUrl}/customers`);
return reply;
getApiClient() 的工作是获取一个已经添加了 Authorization header 的 axios 实例。我是从 Auth0 那里得到的,但这部分并不重要,因为我真的在这里寻找模式而不是 Auth0 的特定模式,可能是任何钩子(Hook):
// 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
由于我的 token 来自钩子(Hook),我应该如何设置它?
我不想每次都这样做:
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`);
Final Solution
看完安德烈所说的内容后,我终于到了我需要去的地方。这是我最终做的:
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 };
之后我也对其进行了很多修改,因为这并不是我真正的用例,但它确定了我不理解的地方。 谢谢安德烈!!!!
最佳答案
这通常通过创建另一个钩子(Hook)来解决,该钩子(Hook)将所有必要的逻辑包装在里面。
Auth0 文档实际上有一个例子:https://github.com/auth0/auth0-react/blob/master/EXAMPLES.md#4-create-a-useapi-hook-for-accessing-protected-apis-with-an-access-token
在你的情况下你可以这样做:
Customers.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
Hook 概括为 useApi
之类的东西,并在 useCustomers
内部简单地调用 useApi
。
您还可以找到官方 Building Your Own Hook文档很有帮助,它解释了最常见的问题。
关于reactjs - 调用 javascript 函数时使用 react hooks 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65499465/