介紹
我有一個螢屏可以對我的服務器進行一些查詢:
按用戶名獲取用戶(當用戶在搜索輸入中輸入內容時)
獲取高級用戶(當螢屏掛載 拉動重繪 時)
獲取年輕用戶(當螢屏掛載時 拉動重繪 )
我正在考慮將其移至掛鉤。
這是我當前的代碼:
function MyScreen() {
// Fetch by username
const [isSearching, setIsSearching] = useState([]);
const [searchedUsers, setSearchedUsers] = useState([]);
// Premium
const [isLoading, setIsLoading] = useState(true); <--- NOTE THIS
const [premiumUsers, setPremiumUsers] = useState([]);
// Young users
const [youngUsers, setYoungUsers] = useState([]);
/*
FIRST METHOD
*/
const searchUsersByUsername = async (limit = 20) => {
setIsSearching(true);
try {
const result = await api.users.searchUsersByUsername(username, limit);
setSearchedUsers(result);
} catch(err) {
console.log(err);
}
setIsSearching(false);
}
/*
SECOND METHOD
*/
const getPremiumUsers = async (limit = 10) => {
// Note: No loading here
try {
const result = await api.users.getPremiumUsers(limit);
setPremiumUsers(result);
} catch(err) {
console.log(err);
}
}
/*
THIRD METHOD
*/
const getYoungUsers = async (limit = 10) => {
// Note: No loading here
try {
const result = await api.users.getYoungUsers(limit);
setYoungUsersUsers(result);
} catch(err) {
console.log(err);
}
}
// Effects and rendering...
useEffect(() => {
(async () => {
const promises = [getPremiumUsers(), getYoungUsers()];
await Promise.all(promises).catch((err) => {
console.log(err))
});
setIsLoading(false); // <---- NOTE THIS
})();
}, []);
}
問題
我無法使用典型的 useQuery 掛鉤,因為我使用的是 Firestore 可呼叫函式。因此,發出請求的唯一方法是呼叫我的 api 方法(api.users.searchUser...)
正如你在代碼中看到的,我有兩種型別的加載指示器(兩種狀態):
isSearching(用于按用戶名搜索功能)
isLoading(用于并行獲取高級用戶和年輕用戶)
我怎樣才能為這個邏輯實作一個可重用的鉤子?
我的意思是,我需要抽象所有這些東西,以便能夠:
Search users by username in other screens
Search premium users (without fetching young users in parallel)
Search young users (without fetching premium users in parallel)
And, also, to get the loading status of the three queries.
Note: In my current screen, as I have said before, I am using "setIsLoading" for the young and premium users parallel fetching, but maybe (to be more flexible) in other screens I will need the loading status for each logic independently.
Any help or ideas?
uj5u.com熱心網友回復:
您可以通過每個 fetch 方法使用React.useEffectand React.useCallback。另外,單獨保存加載狀態。
看一下這個:
import { useEffect, useCallback } from 'react';
const defaultParams = {
fetchPremiumUsersOnMount: false,
fetchYoungUsersOnMount: false,
searchOnMount: false,
username: '',
limit: 20,
}
function useUsersApi(params = defaultParams) {
const [isSearching, setIsSearching] = useState(false);
const [searchedUsers, setSearchedUsers] = useState([]);
const [premiumUsers, setPremiumUsers] = useState([]);
const [premiumLoading, setPremiumLoading] = useState(false);
const [youngUsers, setYoungUsers] = useState([]);
const [youngLoading, setYoungLoading] = useState(false);
const fetchPremiumUsers = useCallback(async () => {
try {
setPremiumLoading(true);
const result = api.users.getPremiumUsers(params.limit);
setPremiumUsers(result);
} catch (err) {
console.log(err)
} finally {
setPremiumLoading(false);
}
}, [params.limit]);
const fetchYoungUsers = useCallback(async () => {
/* similar logic to `fetchPremiumUsers` */
}, [params.limit, params.]);
const fetchSearchUsers = useCallback(async (username) => {
/* fetch logic here */
}, [params.limit]);
useEffect(() => {
if(params.fetchPremiumUsersOnMount) {
fetchPremiumUsers();
}
}, [params.fetchPremiumUsersOnMount, params.limit]);
useEffect(() => {
if(params.fetchYoungUsersOnMount) {
fetchYoungUsers();
}
}, [params.fetchYoungUsersOnMount, params.limit]);
useEffect(() => {
if(params.fetchSearchUsers) {
fetchSearchUser(params.username);
}
}, [params.searchOnMount, params.limit, params.username]);
return {
isSearching,
searchedUsers,
isLoading: premiumLoading || youngLoading,
premiumUsers,
premiumUsersLoading: premiumLoading,
refreshPremiumUsers: fetchPremiumUsers,
youngUsers,
youngUsersLoading: youngLoading,
refreshYoungUsers: fetchYoungUsers,
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/327717.html
標籤:javascript reactjs react-native react-hooks refactoring
上一篇:在ReactNative中使用readAsStringAsync將影像陣列轉換為base64
下一篇:無法解決反應導航/核心
