代码之家  ›  专栏  ›  技术社区  ›  Kristen Grote

当作为Props传递时键入React Infinite查询数据

  •  0
  • Kristen Grote  · 技术社区  · 2 年前

    我使用React Query无限查询加载一个带有“下一步”按钮触发器的条目列表(这是文档中的缩写代码,但想法是一样的):

    import { useInfiniteQuery } from '@tanstack/react-query'
    
    function Projects() {
      const {
        data,
        error,
        fetchNextPage,
        hasNextPage,
        isFetching,
        isFetchingNextPage,
        status,
      } = useInfiniteQuery({
        queryKey: ['projects'],
        queryFn: fetchProjects,
        initialPageParam: 0,
        getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
      })
    
      return (
        <>
          <div>
            {/* [loop through page data] */}
          </div>
          
          <div>
            <button
              onClick={() => fetchNextPage()}
              disabled={!hasNextPage || isFetchingNextPage}
            >
              Next Page
            </button>
          </div>
        </>
      )
    }
    

    当我执行此操作时,Typescript会自动假定Infinite Query变量的类型,如 data , error 使用库提供的类型。现在,我想让Next按钮成为自己的组件,并将Infinite Query变量作为道具传递给它,如下所示:

    // projects.tsx
    
    import { useInfiniteQuery } from '@tanstack/react-query';
    import NextButton from './nextbutton.tsx';
    
    function Projects() {
      const fetchProjects = async ({ pageParam }) => {
        const res = await fetch('/api/projects?cursor=' + pageParam)
        return res.json()
      }
    
      const {
        data,
        error,
        fetchNextPage,
        hasNextPage,
        isFetching,
        isFetchingNextPage,
        status,
      } = useInfiniteQuery({
        queryKey: ['projects'],
        queryFn: fetchProjects,
        initialPageParam: 0,
        getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
      })
    
      const queryData = {
        fetchNextPage: fetchNextPage,
        hasNextPage: hasNextPage,
        isFetchingNextPage: isFetchingNextPage
      }
    
      return (
        <>
          <div>
            {/* [loop through page data] */}
          </div>
    
          <div>
            <NextButton
              queryData={ queryData }
            />
          </div>
        </>
      )
    }
    
    // nextbutton.tsx
    
    export default function NextButton({ queryData }) {
      return (
        <button
          onClick={ () => queryData.fetchNextPage() }
          disabled={ !queryData.hasNextPage || queryData.isFetchingNextPage }
        >
          Next Page
        </button>
      )
    }
    

    问题是,虽然Infinite Query变量在创建时会自动键入,但如果我将它们作为道具传递给单独的组件,则必须再次键入。

    我可以手动写出每个变量的类型,但似乎应该有一种更简单、更少重复的方式来键入它们。如果更容易的话,我可以将所有变量传递给按钮组件,而不是只传递少数变量。

    0 回复  |  直到 2 年前
        1
  •  1
  •   Phil    2 年前

    我可以手动写出每个变量的类型。。。

    这样做。您的组件应该是自包含的,并明确定义它们所期望的道具。它使您的代码可移植、可重用和可测试。

    我也会使用单独的道具,而不是单一的道具 queryData 为了清楚起见。

    您可以直接将按钮道具绑定到React Query中的类型。。。

    import type { UseInfiniteQueryResult } from '@tanstack/react-query';
    
    type NextButtonProps = Pick<
      UseInfiniteQueryResult,
      'fetchNextPage' | 'isFetchingNextPage' | 'hasNextPage'
    >;
    

    或者根据预期用途提供自己的定义。。。

    interface NextButtonProps {
      fetchNextPage: () => void;
      isFetchingNextPage: boolean;
      hasNextPage: boolean;
    }
    

    然后设置组件道具类型。。。

    export default function NextButton({
      fetchNextPage,
      hasNextPage,
      isFetchingNextPage,
    }: NextButtonProps) {
      return (
        <button
          type="button"
          onClick={fetchNextPage}
          disabled={!hasNextPage || isFetchingNextPage}
        >
          Next Page
        </button>
      );
    }
    

    并在父组件中使用它

    <NextButton {...queryData} />
    
    {/* or separate props */}
    
    <NextButton
      fetchNextPage={fetchNextPage}
      isFetchingNextPage={isFetchingNextPage}
      hasNextPage={hasNextPage}
    />
    
        2
  •  0
  •   Balalen    2 年前

    您不需要将整个查询传递给按钮组件,这太过分了

    你需要做的就是传递函数 fetchNextPage() 点击按钮并触发它,下面是一个示例

    <NextButton nextPage={()=>fetchNextPage()} />
    
    
    export default function NextButton({ nextPage }) {
      return (
        <button
          onClick={ nextPage }
        >
          Next Page
        </button>
      )
    }
    
    
    推荐文章