useContractInfiniteReads
Hook for calling multiple ethers Contract read-only methods with "infinite scrolling" ("fetch more") support. Useful for rendering a dynamic list of contract data.
import { useContractInfiniteReads } from 'wagmi'
Usage
The following example uses the more loot contract.
The useContractInfiniteReads
hook requires:
cacheKey
: unique key to store the data in the cachecontracts
: a function that provides aparam
(derived fromgetNextPageParam
orfetchNextPage
) as an argument and expects to return an array of contracts. In the example below,param
is the token ID.
import { BigNumber } from 'ethers'
import { useContractInfiniteReads } from 'wagmi'
import mlootABI from './mlootABI.json'
const mlootContractConfig = {
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
}
function App() {
const { data, fetchNextPage } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{ ...mlootContractConfig, functionName: 'getChest', args },
{ ...mlootContractConfig, functionName: 'getFoot', args },
{ ...mlootContractConfig, functionName: 'getHand', args },
],
},
})
}
You can also optionally provide getNextPageParam
which will derive the param
provided to contracts
. In the example below, we want the param
to increment by 1.
function App() {
const { data, fetchNextPage } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{ ...mlootContractConfig, functionName: 'getChest', args },
{ ...mlootContractConfig, functionName: 'getFoot', args },
{ ...mlootContractConfig, functionName: 'getHand', args },
],
},
getNextPageParam: (_, pages) => pages.length + 1,
})
}
Paginated indexes
Import the paginatedIndexesConfig
helper to assist with paginated indexes. Useful for infinite pagination of token IDs.
In the example below, we are fetching 10 tokenURI
s at a time from the more loot contract.
import { BigNumber } from 'ethers'
import { useContractInfiniteReads, paginatedIndexesConfig } from 'wagmi'
import mlootABI from './mlootABI.json'
const mlootContractConfig = {
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
}
function App() {
const { data, fetchNextPage } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
...paginatedIndexesConfig(
(index) => {
return [
{
...mlootContractConfig,
functionName: 'tokenURI',
args: [BigNumber.from(index)] as const,
},
]
},
{ start: 0, perPage: 10, direction: 'increment' },
),
})
}
Return Value
{
data: {
pages: Result[][]
pageParam: PageParam
}
error?: Error
fetchNextPage: (options?: FetchNextPageOptions) => Promise<Result[]>
hasNextPage: boolean
isIdle: boolean
isLoading: boolean
isFetching: boolean
isFetchingNextPage: boolean;
isSuccess: boolean
isError: boolean
isFetched: boolean
isFetchedAfterMount: boolean
isRefetching: boolean
refetch: (options: {
throwOnError: boolean
cancelRefetch: boolean
}) => Promise<Result>
status: 'idle' | 'error' | 'loading' | 'success'
}
Configuration
cacheKey
Unique key used to store the data in the cache.
import { useContractInfiniteReads } from 'wagmi'
function App() {
const { data, fetchNextPage } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{ ...mlootContractConfig, functionName: 'getChest', args },
{ ...mlootContractConfig, functionName: 'getFoot', args },
{ ...mlootContractConfig, functionName: 'getHand', args },
],
},
})
}
contracts
address
Contract address.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
})
}
abi
Contract ABI.
By defining inline or adding a const assertion to abi
, TypeScript will infer the correct types for functionName
, args
, and hook result. See the wagmi TypeScript docs for more information.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
})
}
functionName
Name of function to call.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
})
}
args
Arguments to pass to function call.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
})
}
chainId
Force a specific chain id for the request. The wagmi Client
's ethers provider
must be set up as a chain-aware function for this to work correctly.
import { useContractReads } from 'wagmi'
import { optimism } from 'wagmi/chains'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
chainId: optimism.id,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
chainId: optimism.id,
},
]
},
})
}
Note: The above example is using the optimism
chain from the wagmi/chains
entrypoint.
getNextPageParam (optional)
Derives the param
provided to contracts
. Provides the last page of the infinite list and an array of pages.
If there is no next page available, return undefined
.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
getNextPageParam: (lastPage, allPages) =>
!lastPage ? allPages.length + 1 : undefined,
})
}
allowFailure (optional)
If a contract read fails while fetching, it will fail silently and not throw an error.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
allowFailure: false,
})
}
overrides (optional)
Overrides to pass to function call.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
overrides: { from: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e' },
})
}
cacheTime (optional)
Time (in ms) which the data should remain in the cache. Defaults to 0
.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
cacheTime: 2_000,
})
}
enabled (optional)
Set this to false
to disable this query from automatically running. Defaults to true
.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
enabled: false,
})
}
isDataEqual (deprecated, optional)
Use structuralSharing
instead.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
isDataEqual: (prev, next) => prev === next,
})
}
staleTime (optional)
Time (in ms) after data is considered stale. If set to Infinity
the data will never be considered stale. Defaults to 0
.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
staleTime: 2_000,
})
}
select (optional)
Transform or select a part of the data returned by the contract.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
select: (data) => transform(data),
})
}
structuralSharing (optional)
Keep referential identity of data and prevent rerenders. Defaults to (oldData, newData) => deepEqual(oldData, newData) ? oldData : replaceEqualDeep(oldData, newData)
. If set to false
, structural sharing between query results will be disabled.
If set to a function, the old and new data values will be passed through this function, which should combine them into resolved data for the query. This way, you can retain references from the old data to improve performance even when that data contains non-serializable values.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
structuralSharing: (prev, next) => (prev === next ? prev : next),
})
}
suspense (optional)
Set this to true
to enable suspense mode.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
suspense: true,
})
}
onSuccess (optional)
Function to invoke when fetching new data is successful.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
onSuccess(data) {
console.log('Success', data)
},
})
}
onError (optional)
Function to invoke when an error is thrown while fetching new data.
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
onError(error) {
console.log('error', error)
},
})
}
onSettled (optional)
Function to invoke when fetching is settled (either successfully fetched, or an error has thrown).
import { useContractInfiniteReads } from 'wagmi'
import { BigNumber } from 'ethers'
function App() {
const { data, isError, isLoading } = useContractInfiniteReads({
cacheKey: 'mlootAttributes',
contracts(param = 0) {
const args = [BigNumber.from(param)] as const
return [
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getChest',
args,
},
{
address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df',
abi: mlootABI,
functionName: 'getWaist',
args,
},
]
},
onSettled(data) {
console.log('Settled', data)
},
})
}