React Hooks - useFetch 泛化

React Hooks - useFetch generalization

我有一个 api,它为我提供了如下方法:

  1. searchUsersByUsername(用户名,限制)
  2. getRandomPremiumUsers(限制)
  3. getYoungUsers(maxAge, limit)

我正在实现一个挂钩“useFetchUsers”,它将提供一个接口来访问这些方法。

这是我当前的代码:

import { useState, useEffect } from "react";

import {
  searchUsersByUsername, 
  getRandomPremiumUsers,
  getRandomYoungUsers,
} from "../../services/firebase/api/users/search"
import { MAX_SEARCH_USERS_BY_USERNAME_TO_RETRIEVE } from "../../utils/search";

export const QUERIES = {
  "SEARCH_USERS_BY_USERNAME": searchUsersByUsername,
  "FETCH_RANDOM_PREMIUM_USERS": getRandomPremiumUsers,
  "FETCH_RANDOM_YOUNG_USERS": getRandomYoungUsers,
};

const defaultOptions = {
  query: QUERIES[0],
  username: "", // optional
  limit = MAX_SEARCH_USERS_BY_USERNAME_TO_RETRIEVE, // optional
};

export default function useFetchUsers(options = defaultOptions, deps) {
  const [users, setUsers] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(undefined);

  const getUsers = async () => {
    setIsLoading(true);

    try {
      const users = await options.query();
      setUsers(users);
    } catch(err) {
      setError(err);
    }

    setIsLoading(false);
  }

  useEffect(getUsers, deps);

  return {
    users,
    isLoading,
    error,
    getUsers
  }
}

我面临的主要问题是,我不知道如何使这个“接口”更加灵活,以便能够将参数传递给我的 QUERY 方法。

此外,我的 defaultOptions 对象不需要“getRandomPremiumUsers”和“getRandomYoungUsers”方法的“用户名”字段。

关于如何在类似的抽象之后满足要求有什么想法吗?

创建方法和return

export default function useFetchUsers() {
  const initialState = {
    payload: null,
    error: null,
    inFlight: false,
  };
  const [result, setResult] = useState(initialState);
  const searchUsersByUsername = () => {
    setResult({ payload: null, error: null, inFlight: true });
    try {
      const payload = fetch("api");
      setResult({ payload, error: null, inFlight: false });
    } catch (error) {
      setResult({ payload: null, error: null, inFlight: false });
    }
  };
  return {
    ...result,
    searchUsersByUsername,
  };
}

编写一个 API 实现抓取逻辑的助手

const api = {
  user: {
    searchUsersByUsername: (option) => {
      return fetch(option);
    },
    getRandomPremiumUsers: (option) => {
      return fetch(option);
    },
    getYoungUsers: (option) => {
      return fetch(option);
    },
  },
};

export default function useFetchUsers() {
  const initialState = {
    payload: null,
    error: null,
    inFlight: false,
  };
  const [result, setResult] = useState(initialState);
  
  const updateState = (fetcher, option) => {
    setResult({ payload: null, error: null, inFlight: true });
    try {
      const payload = fetcher(option);
      setResult({ payload, error: null, inFlight: false });
    } catch (error) {
      setResult({ payload: null, error: null, inFlight: false });
    }
  };
  return {
    ...result,
    updateState,
  };
}

function App() {
  const { updateState, payload } = useFetchUsers();
  return (
    <div
      onclick={() =>
        updateState(api.user.searchUsersByUsername, { username: 'name', limit: 10 })
      }
    >
      searchUsersByUsername
    </div>
  );
}

因此,根据您的用例,您可以在 API 层本身中实现缓存或使用上下文 API

对其进行扩展