基于useFetch思路优化React Hook useFetchUsers适配多查询灵活传参
解决方案
核心优化思路
- 移除所有和具体查询绑定的参数字段(比如
username、maxAge),新增通用的queryArgs数组字段,用来存放传递给查询方法的动态参数 - 简化默认配置,只保留通用的基础配置,避免冗余字段
- 可选优化:给
useEffect依赖设置默认值,减少用户手动传递依赖的出错概率
优化后完整代码
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.SEARCH_USERS_BY_USERNAME, // 默认参数对应默认查询searchUsersByUsername的入参顺序:username、limit queryArgs: ["", MAX_SEARCH_USERS_BY_USERNAME_TO_RETRIEVE], }; // 依赖默认值自动关联查询方法和参数,避免漏传依赖导致不更新 export default function useFetchUsers(options = defaultOptions, deps = [options.query, ...options.queryArgs]) { const [users, setUsers] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(undefined); const getUsers = async () => { setIsLoading(true); setError(undefined); // 每次请求前清空上一次错误 try { // 展开参数数组传入查询方法 const users = await options.query(...options.queryArgs); setUsers(users); } catch(err) { setError(err); } setIsLoading(false); } useEffect(getUsers, deps); return { users, isLoading, error, getUsers } }
三种场景的使用示例
1. 按用户名搜索用户
const { users, isLoading } = useFetchUsers({ query: QUERIES.SEARCH_USERS_BY_USERNAME, // 按参数顺序传入:username、limit queryArgs: [inputUsername, 20] });
2. 获取随机付费用户
const { users, isLoading } = useFetchUsers({ query: QUERIES.FETCH_RANDOM_PREMIUM_USERS, // 按参数顺序传入:limit queryArgs: [10] });
3. 获取年轻用户
const { users, isLoading } = useFetchUsers({ query: QUERIES.FETCH_RANDOM_YOUNG_USERS, // 按参数顺序传入:maxAge、limit queryArgs: [25, 15] });
问题解决说明
- 参数灵活性:不管查询方法需要多少个、什么类型的参数,只需要按调用顺序传入
queryArgs即可,不需要修改Hook的内部结构,后续新增查询方法也不需要调整Hook代码 - 冗余字段消除:移除了和具体查询绑定的
username等字段,不同查询不需要的参数完全不用传递,没有冗余字段问题
内容的提问来源于stack exchange,提问作者Raul
相关产品推荐
相关产品推荐

