> ## Documentation Index
> Fetch the complete documentation index at: https://base-a060aa97-eb-mini-app-ia-overhaul.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuring `useReadContract`

> Configure the properties of the `useReadContract` hook.

# Configuring `useReadContract`

The [`useReadContract`] hook has a number of configurable properties that will allow you to adapt it to your needs. You can combine the functionality of TanStack queries with [`useBlockNumber`] to watch the blockchain for changes, although doing so will consume a number of API calls.

***

## Objectives

By the end of this guide you should be able to:

* Use `useBlockNumber` and the `queryClient` to automatically fetch updates from the blockchain
* Describe the costs of using the above, and methods to reduce those costs
* Configure arguments to be passed with a call to a `pure` or `view` smart contract function
* Call an instance of `useReadContract` on demand
* Utilize `isLoading` and `isFetching` to improve user experience

***

## Fetching Updates from the Blockchain

You'll continue with the project you've been building and last updated while learning about the [`useReadContract` hook].

Once the excitement of your accomplishment of finally reading from your own contract subsides, try using BaseScan to add another issue, or vote on an existing issue. You'll notice that your frontend does **not** update. There are a few ways to handle this.

<Steps>
  <Step title="Fetch updates from the blockchain">
    Use `useBlockNumber` with the `watch` feature to automatically keep track of the block number, then use the `queryClient` to update when that changes. **Make sure** you decompose the `queryKey` from the return of `useReadContract`.

    ```tsx
    import { useEffect, useState } from 'react';
    import { useReadContract, useBlockNumber } from 'wagmi';
    import { useQueryClient } from '@tanstack/react-query';

    // Other Code

    export function IssueList() {
      // Other Code

      const queryClient = useQueryClient();
      const { data: blockNumber } = useBlockNumber({ watch: true });

      const {
        data: issuesData,
        isError: issuesIsError,
        isPending: issuesIsPending,
        queryKey: issuesQueryKey,
      } = useReadContract({
        address: contractData.address as `0x${string}`,
        abi: contractData.abi,
        functionName: 'getAllIssues',
      });

      useEffect(() => {
        queryClient.invalidateQueries({ queryKey: issuesQueryKey });
      }, [blockNumber, queryClient, issuesQueryKey]);

      // Return code
    }
    ```

    <Info>
      Don't do this, either use multi-call via [`useReadContracts`], or consolidate your `view`s into a single function that fetches all the data you need in one call.
    </Info>
  </Step>

  <Step title="Pause on blur">
    Stop watching the blockchain if the website doesn't have focus. Add a state variable to count how many times the function has settled, and one for if the page is focused. Set up event listeners to set the state of the latter when the page is focused or blurred.

    ```tsx
    const [timesCalled, setTimesCalled] = useState(0);
    const [pageIsFocused, setPageIsFocused] = useState(true);

    useEffect(() => {
      const onFocus = () => setPageIsFocused(true);
      const onBlur = () => setPageIsFocused(false);

      window.addEventListener('focus', onFocus);
      window.addEventListener('blur', onBlur);

      return () => {
        window.removeEventListener('focus', onFocus);
        window.removeEventListener('blur', onBlur);
      };
    }, []);
    ```

    Update the `watch` for `useBlockNumber` so that it only does so if `pageIsFocused`.

    ```tsx
    const { data: blockNumber } = useBlockNumber({ watch: pageIsFocused });
    ```

    Add a line to the `useEffect` for `blockNumber` and increment your counter as well.

    ```tsx
    useEffect(() => {
      setTimesCalled((prev) => prev + 1);
      queryClient.invalidateQueries({ queryKey: issuesQueryKey });
    }, [blockNumber, queryClient]);
    ```

    Finally, surface your counter in the component.

    ```tsx
    return (
      <div>
        <h2>Number of times called</h2>
        <p>{timesCalled.toString()}</p>
        <p>{'Has focus: ' + pageIsFocused}</p>
        <h2>All Issues</h2>
        <div>{renderIssues()}</div>
      </div>
    );
    ```
  </Step>

  <Step title="Adjust the polling rate">
    Adjust your [`pollingInterval`] by setting it in `getDefaultConfig` in `_app.tsx`:

    ```tsx
    const config = getDefaultConfig({
      appName: 'RainbowKit App',
      projectId: 'YOUR_PROJECT_ID',
      chains: [baseSepolia],
      ssr: true,
      pollingInterval: 30_000,
    });
    ```

    Setting it to 30 seconds, or 30,000 milliseconds, will reduce your API calls dramatically, without negatively impacting members of the DAO.
  </Step>

  <Step title="Update on demand">
    Use a similar system to call your update function on demand. Add a button, a handler for that button, and a state variable for it to set:

    ```tsx
    const [triggerRead, setTriggerRead] = useState(false);

    const handleTriggerRead = () => {
      setTriggerRead(true);
    };
    ```

    ```tsx
    return (
      <div>
        <button onClick={handleTriggerRead}>Read Now</button>
        <h2>Number of times called</h2>
        <p>{timesCalled.toString()}</p>
        <p>{'Has focus: ' + pageIsFocused}</p>
        <h2>All Issues</h2>
        <div>{renderIssues()}</div>
      </div>
    );
    ```

    Finally, set `watch` to equal `triggerRead`, instead of `pageIsFocused`, and reset `triggerRead` in the `useEffect`.

    ```tsx
    const { data: blockNumber } = useBlockNumber({ watch: triggerRead });

    // Other code...

    useEffect(() => {
      setTriggerRead(false);
      queryClient.invalidateQueries({ queryKey: issuesQueryKey });
    }, [blockNumber, queryClient]);
    ```
  </Step>

  <Step title="Set UI elements based on status">
    Use the "is" return values to set UI elements depending on the status of the hook as it attempts to call a function on the blockchain.

    ```tsx
    <button disabled={issuesIsFetching} onClick={handleTriggerRead}>
      {issuesIsFetching ? 'Loading' : 'Read Now'}
    </button>
    ```

    You'll probably see the button flicker very quickly since the call doesn't take very long. For a production app, you'd need to add additional handling to smooth out the experience.
  </Step>

  <Step title="Pass arguments to useReadContract">
    Arguments are passed into a `useReadContract` hook by adding an array of arguments, in order, to the `args` property. Common practice is to use React state variables set by UI elements to enable the arguments to be set and modified. For example, you might create a drop-down to set `issueNumber`, then fetch that issue with:

    ```tsx
    const [issueNumber, setIssueNumber] = useState(0);

    const { isLoading: getIssueIsLoading } = useReadContract({
      address: contractData.address as `0x${string}`,
      abi: contractData.abi,
      functionName: 'getIssue',
      args: [issueNumber],
    });
    ```
  </Step>
</Steps>

***

## Conclusion

In this guide, you've learned how to use the `watch` feature of `useBlockNumber` combined with `useEffect` and `queryClient.invalidateQueries` to enable your frontend to see updates to your smart contract. You've also learned the costs of doing so, and some strategies for mitigation. You've learned how to pass arguments to your functions. Finally, you've learned how to use the properties returned by `useReadContract` to adjust your UI to improve the experience for your users.

***

[wagmi]: https://wagmi.sh/

[`useReadContract`]: https://wagmi.sh/react/hooks/useReadContract

[`useReadContract` hook]: ./useReadContract

[`useBlockNumber`]: https://wagmi.sh/react/api/hooks/useBlockNumber

[removed]: https://wagmi.sh/react/guides/migrate-from-v1-to-v2#removed-watch-property

[`useReadContracts`]: https://wagmi.sh/react/hooks/useReadContracts

[`pollingInterval`]: https://wagmi.sh/react/api/createConfig#pollinginterval
