[英]How to call react hook inside of a react useCallback
我有一個 next.js 反應應用程序。
我的應用程序中有一部分稱為“橫幅”,我正在使用上下文 API 構建“商店”。但是,當我在頁面中調用“useFetchBanners”function 時,出現以下錯誤。 這個function用來設置頁面的初始state。
- 無法在回調內調用 React Hook“useFetchBanners”。 React Hooks 必須在 React function 組件或自定義 React Hook function 中調用。[Error/react-hooks/rules-of-hooks]
橫幅商店.tsx
import { createContext, useCallback, useContext, useState } from "react";
import { AppContext } from "src/contexts/app/AppContext";
import { GetBanners, IGetBannersQuery, IGetBannersResponse } from "src/services/BannersService.";
interface IBannerStore {
isLoading: boolean;
}
const useStore = () => {
const appContext = useContext(AppContext);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [data, setData] = useState<IGetBannersResponse | null>(null);
const [error, setError] = useState<any>(null);
const [searchQuery, setSearchQuery] = useState<IGetBannersQuery>({});
const fetchBanners = async (params: IGetBannersQuery) => {
const [results, error] = await GetBanners(params, appContext.token);
if (results.status !== 200 || error) {
setError(error);
}
setData(results.data || null);
};
return {
isLoading,
setIsLoading,
data,
setData,
searchQuery,
setSearchQuery,
fetchBanners: (params: IGetBannersQuery) => fetchBanners(params),
};
};
const StoreContext = createContext<any>(null);
export const StoreContextProvider = ({ children }: any) => <StoreContext.Provider value={useStore()}>{children}</StoreContext.Provider>;
export const useIsLoading = () => useContext(StoreContext).isLoading;
export const useSetIsLoading = () => useContext(StoreContext).setIsLoading;
export const useData = () => useContext(StoreContext).data;
export const useSetData = () => useContext(StoreContext).setData;
export const useSearchQuery = () => useContext(StoreContext).searchQuery;
export const useSetSearchQuery = () => useContext(StoreContext).setSearchQuery;
export const useFetchBanners = (params: IGetBannersQuery) => useContext(StoreContext).fetchBanners;
我想在頁面加載時調用 function useFetchBanners
來設置初始數據。 (考慮到可能存在的現有瀏覽器參數)
橫幅頁面.tsx
...
const init = useCallback(async () => {
if (router.isReady === false) {
return;
}
let loadBrowserSearchParams = null;
if (!_.isEmpty(router.query)) {
loadBrowserSearchParams = {
...
}
}
// error here
useFetchBanners(loadBrowserSearchParams);
}, [router]);
useEffect(() => {
init();
}, [init, router]);
...
似乎我無法在 useCallback 中調用我的 useFetchBanners。
我認為您的鈎子已經正確編寫,您只需要以不同的方式使用它。 在您的組件主體中調用它,它會返回一個 function 給您,然后您可以稍后調用該 function。
// bannersPage.tsx
const fetchBanners = useFetchBanners();
const init = useCallback(async () => {
if (router.isReady === false) {
return;
}
let loadBrowserSearchParams = null;
if (!_.isEmpty(router.query)) {
loadBrowserSearchParams = {
...
};
}
fetchBanners(loadBrowserSearchParams);
}, [router]);
useEffect(() => {
init();
}, [init, router]);
PS,如果效果中只需要init
function,可以移到效果里面:
const fetchBanners = useFetchBanners();
useEffect(() => {
if (router.isReady === false) {
return;
}
let loadBrowserSearchParams = null;
if (!_.isEmpty(router.query)) {
loadBrowserSearchParams = {
...
};
}
fetchBanners(loadBrowserSearchParams);
}, [router]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.