# Rendering NFTs owned

**All the code will be inserted into the MainMenu file**

Now that we have a function to fetch all NFTs owned by the user, we want to give him an interface to see them. For this, we will have to store the complete list of ids using a constant inside the `MainMenu` component. We will be doing this using the same `React State hook`, so import it into `MainMenu.js` file. In addition, `React Callback hook` will be needed.

```jsx
import React, { useEffect, useState, useCallback } from 'react';
```

### Create the needed states

After importing the needed `hooks`, the next step is creating the `constant` to store the results. It will be a `constant` having attached a `function` to access its value by the `State hook`. We initialize it having the value of an empty list `[]`. Also, we will need a `boolean constant` to record whether the API has responded and we can start rendering the results. When first getting on the `MainMenu`, obviously the `results` haven’t already been obtained, this is why we are initializing our constant being `false`.

```jsx
const [NFTsOwned, setNFTsOwned] = useState([]);
const [hasRespondedNFTs, setHasRespondedNFTs] = useState(false);
```

### Ensure waiting for the results by an async function

An `arrow function` that does the fetching steps will be needed, too. Keeping in evidence the fact that we need to `wait` for the response, the constant will be an `asynchronous` one. We are going to use the `Callback hook` because we only need to execute it once, unless the `userAddress` is modified. This is why `userAddress` is the unique `Callback parameter`.

```jsx
const fetchNFTsOwned = useCallback(async () => {
  let localNFTsOwned = await getNFTsOwned(userAddress);
  setHasRespondedNFTs(true);
  if (localNFTsOwned) setNFTsOwned(localNFTsOwned);
  else setNFTsOwned([]);
}, [userAddress]);
```

As you see above, after waiting for the API’s response, we will set the `hasRespondedNFTs` constant’s value to `true`, meaning the interaction with the API has completed. If the local variable `localNFTsOwned` has at least one value, we will set the `NFTsOwned` constant’s value to the respective list of ids. If not, `NFTsOwned` will keep having the empty list `[]` value meaning the user does not own any NFTs. To give functionality to our `fetchNFTsOwned` constant, we will call it using the `Effect hook` previously explained. To cover any eventual changes to the user wallet balance, we are going to set an interval of 30 seconds in which the execution thread will be reloaded and the NFTs list will be updated.

```jsx
useEffect(() => {
  fetchNFTsOwned();
  setInterval(() => {}, 30000);
}, [fetchNFTsOwned]);
```

### Render based on previous states

Using `NFTsOwned` and `hasRespondedNFTs` states, we can build the cases in which the user can fit.

1. The first one is when the API `hasn’t responded` yet. So we will return the corresponding `<HTML>` content which sends the message that the NFTs are still loading:

   ```jsx
   {!hasRespondedNFTs && <h1> Loading NFTs... </h1>}
   ```
2. The second one is when the API `has responded`, but the user does `not own any NFTs`:

   ```jsx
   {hasRespondedNFTs && NFTsOwned.length == 0 && <h1> No NFTs available </h1>}
   ```
3. The last one happens when the API `has responded`, and the user `owns at least one NFT`:

   ```jsx
   {hasRespondedNFTs && NFTsOwned.length > 0 && (
     <div>
       <h2>Pick your NFT!</h2>
       {NFTsOwned.map((nftId) => (
         <span id={`nft${nftId}`} key={nftId}>
           <img
             src={`https://stacksgamefi.mypinata.cloud/ipfs/QmNz74TN66hgi9X4wZ1ch9hXKxaywG5soEQPMfDqEMLVsd/${nftId}.png`}
             alt={`duck ${nftId}`}
             width="50"
           ></img>
           {`NFT#${nftId}`}
         </span>
       ))}
     </div>
   )}
   ```

### Render and return the NFTs by cases

The `.map()` does nothing but mapping each `nftId` from `NFTsOwned` to its corresponding `<HTML>` representation for the user experience. This way the user will see all the NFTs with the corresponding images and a suggestive name below each image. As you see above, the `<img>`'s `src` is written using the base `Pinata url` and the NFT’s `id` which could be found in `NFTsOwned` list. The final look of the `returned` content inside `MainMenu` will be the following:

```jsx
return (
  <div>
    <header className="App-header">
      <h1>Integrate NFTs Into GameFi</h1>
      <h6>{`Current user address: ${userAddress}`}</h6>
      {!hasRespondedNFTs && <h1> Loading NFTs... </h1>}
      {hasRespondedNFTs && NFTsOwned.length == 0 && <h1> No NFTs available </h1>}
      {hasRespondedNFTs && NFTsOwned.length > 0 && (
        <div>
          <h2>Pick your NFT!</h2>
          {NFTsOwned.map((nftId) => (
            <span id={`nft${nftId}`} key={nftId}>
              <img
                src={`https://stacksgamefi.mypinata.cloud/ipfs/QmNz74TN66hgi9X4wZ1ch9hXKxaywG5soEQPMfDqEMLVsd/${nftId}.png`}
                alt={`duck ${nftId}`}
                width="50"
              ></img>
              {`NFT#${nftId}`}
            </span>
          ))}
        </div>
      )}
      <button className="Connect" onClick={disconnect}>
        Disconnect Wallet
      </button>
      <br></br>
      <a className="App-link" href="<https://stacksdegens.com/>" target="_blank">
        Build by Stacks Degens
      </a>
    </header>
  </div>
);
```

After completing this step, our `MainMenu` offers the user an interface where he can see all the NFTs he owns. Next, we want to give him the possibility to click each one in order to select it and finally play using it.

## This is the branch with the changes done:

{% embed url="<https://github.com/BowTiedDeployer/workshop-nft-integration/tree/dapp/3-render-nfts>" %}
branch dapp/3-render-nfts
{% endembed %}

You can check the exact changes in this commit referring to them

{% embed url="<https://github.com/BowTiedDeployer/workshop-nft-integration/commit/fefbfad13534d0c208dc3e990b876ac620062631>" %}
commit fefbfad13534d0c208dc3e990b876ac620062631
{% endembed %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.degenlab.io/gamefistacks/workshop/nft-web-app-integration/rendering-nfts-owned.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
