javascript - 在不转换为异步函数的情况下无法从函数内部的本地存储中获取值
问题描述
我已经为我在 react-native 中的 API 调用制作了一个 fetch 函数的包装器。我不想每次进行 API 调用时都传递 JWT 令牌,所以我认为在包装器中获取它会为我修复它,但由于异步性质,我无法让它工作......
使用Fetch.js
// import qs from "querystring";
import { getUserAuthToken } from "../storage";
const responseChecker = async (response) => {
let error = "";
let data = {};
let statusCode = null;
if (!response.ok) {
error = "Something went wrong";
statusCode = response.status;
} else {
statusCode = response.status;
data = await response.json();
}
return { statusCode, error, data };
};
const fetchAuthToken = getUserAuthToken();
const useFetch = (baseURL, authHeader = null) => {
console.log(fetchAuthToken);
**//Cannot get this token in time for the API call ^**
const defaultHeader = {
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
key: "1c419c7e-3a34-49f0-9192-b48d4534dff3",
Authorization: authHeader ? authHeader :fetchAuthToken,
};
const customFetch = (
url,
method = "GET",
body = false,
headers = defaultHeader,
) => {
const options = {
method,
headers,
credentials: "include",
};
if (body) options.body = body;
return fetch(url, options);
};
const get = async (endpoint) => {
const url = `${baseURL}${endpoint}`;
const response = await customFetch(url, "GET");
return responseChecker(response);
};
const post = async (endpoint, body = {}) => {
const url = `${baseURL}${endpoint}`;
const response = await customFetch(url, "POST", body);
return responseChecker(response);
};
const put = async (endpoint, body = {}) => {
const url = `${baseURL}${endpoint}`;
const response = await customFetch(url, "PUT", body);
return responseChecker(response);
};
return {
get,
post,
put,
};
};
export default useFetch;
存储.js
import AsyncStorage from "@react-native-community/async-storage";
export const getUserAuthToken = async () => {
try {
const userToken = await AsyncStorage.getItem("userAuthToken");
return userToken;
} catch (e) {
console.log("error");
}
};
导出API.js
import useFetch from "./fetch";
const LOCAL_IP = "192.168.0.131";
export const authAPI = (header) => useFetch(`http://${LOCAL_IP}:8000`, header);
export const activityAPI = useFetch(`http://${LOCAL_IP}:8000`);
步骤.js
import React, { useEffect, useState } from "react";
import { Text, Platform } from "react-native";
import { CardXLarge } from "../../../components/Cards/";
import fitnessKitApis from "../../../utilities/fitnessKits";
import { activityAPI } from "../../../utilities/apis";
const StepCard = (props) => {
const fetchStepsFromFitnessKits = async () => {
if (Platform.OS === "android") {
await fitnessKitApis.historicSteps().then((res) => {
setSteps(res);
});
} else {
await fitnessKitApis.historicSteps((result) => setSteps(result));
}
};
const [steps, setSteps] = useState(0);
useEffect(() => {
fetchStepsFromFitnessKits();
const requestParams = { date: new Date(), steps };
const { data, statusCode, error } = activityAPI.get(
"/v1/user/steps/",
requestParams,
);
// console.log(data, statusCode, error);
}, [steps]);
return (
<CardXLarge>
<Text>{steps}</Text>
</CardXLarge>
);
};
export default StepCard;
我知道我可以从组件传递 authHeader ,但这会导致在每个组件中添加 2-3 行代码,这不是超级方便。谢谢
解决方案
我将 getUserAuthToken 函数移至 useFetch 函数中的每个请求方法函数,我可以在其中等待响应。然后一切都很完美..我也可以使用 getUserAuthToken 但 usingAsyncStorage.getItem 似乎更干净
修改 fetch.js
// import qs from "querystring";
import AsyncStorage from "@react-native-community/async-storage";
const responseChecker = async (response) => {
let error = "";
let data = {};
let statusCode = null;
if (!response.ok) {
error = "Something went wrong";
statusCode = response.status;
} else {
statusCode = response.status;
data = await response.json();
}
return { statusCode, error, data };
};
const useFetch = (baseURL, authHeader = null) => {
const defaultHeader = {
Accept: "application/json",
// "Content-Type": "application/x-www-form-urlencoded",
"Content-Type": "application/json",
key: "1c419c7e-3a34-49f0-9192-b48d4534dff3",
Authorization: authHeader,
};
const customFetch = (
url,
method = "GET",
body = false,
headers = defaultHeader,
) => {
const options = {
method,
headers,
credentials: "include",
};
if (body) options.body = JSON.stringify(body);
return fetch(url, options);
};
const get = async (endpoint) => {
await AsyncStorage.getItem("userAuthToken").then((result) => {
defaultHeader.Authorization = result;
});
const url = `${baseURL}${endpoint}`;
const response = await customFetch(url, "GET");
return responseChecker(response);
};
const post = async (endpoint, body = {}) => {
await AsyncStorage.getItem("userAuthToken").then((result) => {
defaultHeader.Authorization = result;
});
const url = `${baseURL}${endpoint}`;
const response = await customFetch(url, "POST", body);
return responseChecker(response);
};
const put = async (endpoint, body = {}) => {
await AsyncStorage.getItem("userAuthToken").then((result) => {
defaultHeader.Authorization = result;
});
const url = `${baseURL}${endpoint}`;
const response = await customFetch(url, "PUT", body);
return responseChecker(response);
};
return {
get,
post,
put,
};
};
export default useFetch;
推荐阅读
- node.js - 在 npm 审计修复后如何解决原型污染 lodash 需要手动审查
- vuejs2 - 如何获取子组件的高度?
- python - 如何检查 Cerberus 中的参照完整性?
- android - java.lang.IllegalStateException:已经在池中
- swift - 如何关闭导航控制器?
- android - 在 PreferenceScreen 和 Code 中共享设置名称和默认值
- ios - 是否多次完成导航加载
- python-3.x - 如何在 pandas 数据框中的多个列上执行分组并在 python 中使用 fbProphet 预测未来值?
- c - 我需要帮助在 C 中从中缀转换为后缀
- laravel - Laravel:REJECT ROUTE 未定义但存在于 web.php 中