View from Modules
The useViewModule hook is a React hook that allows you to call view functions from modules on the Aptos blockchain. These functions allow you to query the state of the blockchain in a read-only manner. This guide is
a basic example of how to use the useViewModule hook to view the APT balance of an account.
Getting Started
Create a AccountBalance Component
Create a new component called AccountBalance. This component will display the balance of an account. This component will accept an accountAddress prop, which is the address of the account to display the balance of. It will
use the useViewModule hook to fetch the balance of the account by calling the 0x1::coin::balance view function and passing in the accountAddress as an argument and the 0x1::aptos_coin::AptosCoin
type argument.
import { useViewModule } from "@aptos-labs/react";
interface AccountBalanceProps {
accountAddress: string;
}
export default function AccountBalance({
accountAddress,
}: AccountBalanceProps) {
const { data: balance, isLoading } = useViewModule({
payload: {
function: "0x1::coin::balance",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [accountAddress],
},
});
return (
<div>
{accountAddress} APT Balance: {balance ?? "0"}
</div>
);
}Additionally, if the useViewModule depends on an argument, you can use the enabled prop to fetch the data only when the argument is provided.
import { useViewModule } from "@aptos-labs/react";
interface AccountBalanceProps {
accountAddress?: string;
}
export default function AccountBalance({
accountAddress,
}: AccountBalanceProps) {
const { data: balance, isLoading } = useViewModule({
payload: {
function: "0x1::coin::balance",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [accountAddress],
},
enabled: accountAddress !== undefined,
});
return (
<div>
{accountAddress} APT Balance: {balance ?? "0"}
</div>
);
}Handling Loading and Error States
It is important to handle errors and loading states to maintain a transparent user experience. The useViewModule hook exposes the isLoading and error properties which can be used to display a loading state and handle errors.
import { useViewModule } from "@aptos-labs/react";
interface AccountBalanceProps {
accountAddress?: string;
}
export default function AccountBalance({
accountAddress,
}: AccountBalanceProps) {
const {
data: balance,
isLoading,
error,
} = useViewModule({
payload: {
function: "0x1::coin::balance",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [accountAddress],
},
enabled: accountAddress !== undefined,
});
if (isLoading) {
return <div>Loading...</div>;
}
if (error) {
return (
<div>
Error: {"shortMessage" in error ? error.shortMessage : error.message}
</div>
);
}
return (
<div>
{accountAddress} APT Balance: {balance ?? "0"}
</div>
);
}Refetching Data
The useViewModule hook returns a refetch function which can be used to refetch the data. This is useful if you need to refresh the data.
import { useViewModule } from "@aptos-labs/react";
interface AccountBalanceProps {
accountAddress?: string;
}
export default function AccountBalance({
accountAddress,
}: AccountBalanceProps) {
const {
data: balance,
isLoading,
error,
refetch,
} = useViewModule({
payload: {
function: "0x1::coin::balance",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [accountAddress],
},
enabled: accountAddress !== undefined,
});
if (isLoading) {
return <div>Loading...</div>;
}
if (error) {
return (
<div>
Error: {"shortMessage" in error ? error.shortMessage : error.message}
</div>
);
}
return (
<div>
{accountAddress} APT Balance: {balance ?? "0"}
<button onClick={refetch}>Refresh</button>
</div>
);
}Alternatively, you can use query invalidation to refetch the data. To do this, you can use the queryClient from the useQueryClient hook from @tanstack/react-query. To invalidate the query, you must also
pass in a query key to the invalidateQueries function.
import { useViewModule, useNetwork } from "@aptos-labs/react";
import { useQueryClient } from "@tanstack/react-query";
interface AccountBalanceProps {
accountAddress?: string;
}
export default function AccountBalance({
accountAddress,
}: AccountBalanceProps) {
const queryClient = useQueryClient();
const { network } = useNetwork();
const payload = {
function: "0x1::coin::balance",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [accountAddress],
};
const {
data: balance,
isLoading,
error,
} = useViewModule({
payload,
enabled: accountAddress !== undefined,
});
const handleRefresh = () => {
queryClient.invalidateQueries({
queryKey: getViewModuleQueryKey({ payload, network }),
});
};
if (error) {
return (
<div>
Error: {"shortMessage" in error ? error.shortMessage : error.message}
</div>
);
}
return (
<div>
{accountAddress} APT Balance: {balance ?? "0"}
<button onClick={handleRefresh}>Refresh</button>
</div>
);
}