当 graphql 变量的状态发生变化时,结果在 react-native 上保持不变
When state changes for graphql variable, result stays the same on react-native
我正在尝试使用 shopify graphql 创建一个应用程序 api 以在 React Native expo 上创建一个电子商务应用程序。
我有一个 onPress 调用 setState 来更改 graphQL 变量的状态,但结果不会从 'currentSubCategories'
的初始状态改变
const [currentSubCategories, setSubCategories] = useState(Categories[0].subCategory[0].handle);
let {
collection,
loading,
hasMore,
refetch,
isFetchingMore,
} = useCollectionQuery(currentSubCategories, first, priceRange);
const [currentCategory, setCategory] = useState({categories: Categories[0]});
const onSubCategorySelect = (subCategory) => { setSubCategories(subCategory.handle) }
onPress={() => onSubCategorySelect(item)}
function useCollectionQuery(
collectionHandle: string,
first: number,
priceRange: [number, number],
) {
let [isInitFetching, setInitFetching] = useState<boolean>(true);
let [isReloading, setIsReloading] = useState<boolean>(true);
let [collection, setCollection] = useState<Array<Product>>([]);
let isFetchingMore = useRef<boolean>(false);
let hasMore = useRef<boolean>(true);
let defaultCurrency = useDefaultCurrency().data;
let { data, loading, refetch: refetchQuery } = useQuery<
GetCollection,
GetCollectionVariables
>(GET_COLLECTION, {
variables: {
collectionHandle,
first,
sortKey: ProductCollectionSortKeys.BEST_SELLING,
presentmentCurrencies: [defaultCurrency],
},
notifyOnNetworkStatusChange: true,
fetchPolicy: 'no-cache',
});
let getMoreUntilTarget = async (
targetAmount: number,
cursor: string | null,
handle: string,
filter: [number, number],
) => {
let result: Array<Product> = [];
let moreData: Array<Product> = [];
let { data } = await refetchQuery({
first,
collectionHandle: handle,
after: cursor,
});
...
useEffect(() => {
if (!loading) {
isFetchingMore.current = false;
}
if (isInitFetching && !!data && !!data.collectionByHandle) {
let newCollection = mapToProducts(data.collectionByHandle.products);
hasMore.current = !!data.collectionByHandle?.products.pageInfo
.hasNextPage;
setCollection(newCollection);
setIsReloading(false);
setInitFetching(false);
}
}, [loading, isInitFetching]); // eslint-disable-line react-hooks/exhaustive-deps
return {
collection,
loading: isReloading,
hasMore: hasMore.current,
isFetchingMore: isFetchingMore.current,
refetch,
};
}
我正在使用 flatList 来显示结果
<FlatList
data={collection}
renderItem={({ item }) => (
<Text>{item.title}</Text>
)}
/>
根据 docs 你必须传递新变量来重新获取,否则重新获取将使用初始值。
在这种情况下(自定义挂钩)您有两种方法可以解决此问题:
- return
variables
来自您的自定义挂钩(取自 useQuery
),
- return 一些自己的
refetch
函数。
第一个选项需要 'manual' variables
更新为:
refetch( { ...variablesFromHook, collectionHandle: currentSubCategories } );
在第二种情况下,您可以使用 collectionHandle
参数创建 myRefetch
(和 return 作为 refetch
)以使用更新的变量调用 refetch
- 隐藏 'complexity' 在你的钩子里。
两种情况都需要 refetch
在更新状态后调用 (setSubCategories
) 所以你应该在 useEffect
中使用这个 refetch
具有 [currentSubCategories]
依赖性...或者根本不使用状态,直接从事件处理程序调用 refetch
(在 onSubCategorySelect
中)。
我正在尝试使用 shopify graphql 创建一个应用程序 api 以在 React Native expo 上创建一个电子商务应用程序。
我有一个 onPress 调用 setState 来更改 graphQL 变量的状态,但结果不会从 'currentSubCategories'
的初始状态改变
const [currentSubCategories, setSubCategories] = useState(Categories[0].subCategory[0].handle);
let {
collection,
loading,
hasMore,
refetch,
isFetchingMore,
} = useCollectionQuery(currentSubCategories, first, priceRange);
const [currentCategory, setCategory] = useState({categories: Categories[0]});
const onSubCategorySelect = (subCategory) => { setSubCategories(subCategory.handle) }
onPress={() => onSubCategorySelect(item)}
function useCollectionQuery(
collectionHandle: string,
first: number,
priceRange: [number, number],
) {
let [isInitFetching, setInitFetching] = useState<boolean>(true);
let [isReloading, setIsReloading] = useState<boolean>(true);
let [collection, setCollection] = useState<Array<Product>>([]);
let isFetchingMore = useRef<boolean>(false);
let hasMore = useRef<boolean>(true);
let defaultCurrency = useDefaultCurrency().data;
let { data, loading, refetch: refetchQuery } = useQuery<
GetCollection,
GetCollectionVariables
>(GET_COLLECTION, {
variables: {
collectionHandle,
first,
sortKey: ProductCollectionSortKeys.BEST_SELLING,
presentmentCurrencies: [defaultCurrency],
},
notifyOnNetworkStatusChange: true,
fetchPolicy: 'no-cache',
});
let getMoreUntilTarget = async (
targetAmount: number,
cursor: string | null,
handle: string,
filter: [number, number],
) => {
let result: Array<Product> = [];
let moreData: Array<Product> = [];
let { data } = await refetchQuery({
first,
collectionHandle: handle,
after: cursor,
});
...
useEffect(() => {
if (!loading) {
isFetchingMore.current = false;
}
if (isInitFetching && !!data && !!data.collectionByHandle) {
let newCollection = mapToProducts(data.collectionByHandle.products);
hasMore.current = !!data.collectionByHandle?.products.pageInfo
.hasNextPage;
setCollection(newCollection);
setIsReloading(false);
setInitFetching(false);
}
}, [loading, isInitFetching]); // eslint-disable-line react-hooks/exhaustive-deps
return {
collection,
loading: isReloading,
hasMore: hasMore.current,
isFetchingMore: isFetchingMore.current,
refetch,
};
}
我正在使用 flatList 来显示结果
<FlatList
data={collection}
renderItem={({ item }) => (
<Text>{item.title}</Text>
)}
/>
根据 docs 你必须传递新变量来重新获取,否则重新获取将使用初始值。
在这种情况下(自定义挂钩)您有两种方法可以解决此问题:
- return
variables
来自您的自定义挂钩(取自useQuery
), - return 一些自己的
refetch
函数。
第一个选项需要 'manual' variables
更新为:
refetch( { ...variablesFromHook, collectionHandle: currentSubCategories } );
在第二种情况下,您可以使用 collectionHandle
参数创建 myRefetch
(和 return 作为 refetch
)以使用更新的变量调用 refetch
- 隐藏 'complexity' 在你的钩子里。
两种情况都需要 refetch
在更新状态后调用 (setSubCategories
) 所以你应该在 useEffect
中使用这个 refetch
具有 [currentSubCategories]
依赖性...或者根本不使用状态,直接从事件处理程序调用 refetch
(在 onSubCategorySelect
中)。