当 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 中)。