React Hooks - useFetch 泛化
React Hooks - useFetch generalization
我有一个 api,它为我提供了如下方法:
- searchUsersByUsername(用户名,限制)
- getRandomPremiumUsers(限制)
- 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
对其进行扩展
我有一个 api,它为我提供了如下方法:
- searchUsersByUsername(用户名,限制)
- getRandomPremiumUsers(限制)
- 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
对其进行扩展