首页 > 解决方案 > 在不转换为异步函数的情况下无法从函数内部的本地存储中获取值

问题描述

我已经为我在 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 行代码,这不是超级方便。谢谢

标签: javascriptreactjsreact-nativeasynchronous

解决方案


我将 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;


推荐阅读