我正在使用 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 使用库提供的类型自动假定无限查询变量的类型,例如
data
、error
等。现在,我想让“下一步”按钮成为它自己的组件,并将无限查询变量作为道具传递给它,如下所示:
// 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>
)
}
问题在于,虽然无限查询变量在创建时会自动输入,但如果我将它们作为道具传递给单独的组件,则必须再次输入它们。
我可以手动写出每个变量的类型,但似乎应该有一种更简单、更少重复的方法来键入它们。如果更容易的话,我可以将所有变量传递给按钮组件,而不是只传递少数变量。
我可以手动写出每个变量的类型...
这样做。您的组件应该是独立的,并明确定义它们期望的 props。它使您的代码可移植、可重用和可测试。
为了清楚起见,我还会使用单独的道具而不是单个
queryData
对象。
interface NextButtonProps {
fetchNextPage: () => void;
hasNextPage: boolean;
isFetchingNextPage: boolean;
}
export default function NextButton({
fetchNextPage,
hasNextPage,
isFetchingNextPage,
}: NextButtonProps) {
return (
<button
onClick={fetchNextPage}
disabled={!hasNextPage || isFetchingNextPage}
>
Next Page
</button>
);
}
然后你可以在你的父组件中使用它
<NextButton {...queryData} />
{/* or separate props */}
<NextButton
fetchNextPage={fetchNextPage}
hasNextPage={hasNextPage}
isFetchingNextPage={isFetchingNextPage}
/>