Building a React App to Fetch and Display BTC Unspent Outputs: A Beginner’s Guide

Diving into different technologies can be both exciting and daunting. One effective way to master new skills is by working on real-world projects. Today, I’m sharing my experience developing a React application to fetch and display Bitcoin (BTC) unspen…


This content originally appeared on DEV Community and was authored by mibii

Diving into different technologies can be both exciting and daunting. One effective way to master new skills is by working on real-world projects. Today, I’m sharing my experience developing a React application to fetch and display Bitcoin (BTC) unspent outputs. This journey covers various technologies, including React, Tailwind CSS, and working with APIs. Let’s break it down into key moments and learnings.

Image description

Setting Up the Project

Initializing the React App

First, set up your React project using Create React App. This command-line tool simplifies the process of setting up a new React project with a pre-configured development environment.


npx create-react-app btc-unspent-outputs
cd btc-unspent-outputs

Installing Tailwind CSS

Tailwind CSS is a utility-first CSS framework that helps you quickly style your application. It’s highly customizable and perfect for building modern web applications.


npm install -D tailwindcss
npx tailwindcss init

Configure Tailwind in tailwind.config.js and include it in your CSS files.


// tailwind.config.js
module.exports = {
  purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}


/* index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

Developing the Application

Managing State and Form Submission

We use React’s useState to manage the state for unspent outputs, the BTC address input, loading state, and pagination. Handling form submission involves fetching unspent outputs for the provided BTC address.


import React, { useState } from 'react';

function App() {
  const [outputs, setOutputs] = useState([]);
  const [address, setAddress] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage] = useState(10);

  const handleSubmit = (e) => {
    e.preventDefault();
    setIsLoading(true);
    fetchUnspentOutputs(address)
      .then(data => {
        setOutputs(data);
        setIsLoading(false);
        setCurrentPage(1);
      })
      .catch(err => {
        console.error('Error fetching unspent outputs:', err);
        setOutputs([]);
        setIsLoading(false);
      });
  };

  const fetchUnspentOutputs = async (btcAddress) => {
    const response = await fetch(`https://blockchain.info/unspent?active=${btcAddress}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    if (!data.unspent_outputs || !Array.isArray(data.unspent_outputs)) {
      throw new Error('Invalid response format');
    }
    return data.unspent_outputs.map((output) => ({
      txHash: output.tx_hash_big_endian,
      outputIndex: output.tx_output_n,
      value: output.value / 100000000,
      confirmations: output.confirmations
    }));
  };

  const formatBTC = (btc) => {
    return btc.toLocaleString('en-US', {
      minimumFractionDigits: 8,
      maximumFractionDigits: 8
    });
  };
}

Validating BTC Address

To ensure the user inputs a valid BTC address, we use the bitcoin-address-validation library. This helps prevent unnecessary API calls with invalid addresses.


npm install bitcoin-address-validation


import validate from 'bitcoin-address-validation';

// Inside handleSubmit function
if (!validate(address)) {
  alert('Please enter a valid BTC address');
  setIsLoading(false);
  return;
}

Displaying Data in a Table

Once the data is fetched, we display it in a table. We ensure that each transaction hash is clickable, leading to a detailed view on a blockchain explorer.


// Inside the return statement
<div className="overflow-x-auto">
  <table className="min-w-full divide-y divide-gray-200">
    <thead className="bg-gray-50">
      <tr>
        <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Transaction Link</th>
        <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Transaction Hash</th>
        <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Output Index</th>
        <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Value (BTC)</th>
        <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Confirmations</th>
      </tr>
    </thead>
    <tbody className="bg-white divide-y divide-gray-200">
      {outputs.map((output, index) => (
        <tr key={index}>
          <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 break-all">
            <a href={`https://www.blockchain.com/explorer/transactions/btc/${output.txHash}`} target="_blank" rel="noopener noreferrer">
              url_link_check_tx_hash
            </a>
          </td>
          <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
            {output.txHash}
          </td>
          <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
            {output.outputIndex}
          </td>
          <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
            {formatBTC(output.value)}
          </td>
          <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
            {output.confirmations}
          </td>
        </tr>
      ))}
    </tbody>
  </table>
</div>

Pagination

To handle pagination, we slice the data array and display a subset of items based on the current page and items per page. We also add buttons to navigate between pages.


const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
const currentOutputs = outputs.slice(indexOfFirstItem, indexOfLastItem);

const paginate = (pageNumber) => setCurrentPage(pageNumber);

// Pagination buttons inside return statement
<div className="flex justify-center items-center mt-4 space-x-2">
  <button onClick={() => paginate(currentPage - 1)} disabled={currentPage === 1} className="px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 disabled:bg-gray-200 disabled:text-gray-400">&lt;</button>
  <span className="text-sm text-gray-700">Page {currentPage}</span>
  <button onClick={() => paginate(currentPage + 1)} disabled={indexOfLastItem >= outputs.length} className="px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 disabled:bg-gray-200 disabled:text-gray-400">&gt;</button>
</div>

Deployed - https://btcunspentoutputchecker.netlify.app/

Conclusion

Building this React application to fetch and display BTC unspent outputs has been an enlightening experience. It not only reinforces your React and Tailwind CSS skills but also teaches you how to work with external APIs and handle data efficiently. This project is a great example of how combining different technologies can result in a powerful and functional web application.

For beginners, the key takeaways are:

  • State Management: Using React’s useState to manage different states in the application.
  • Form Handling: Implementing form submission and data fetching with proper error handling.
  • Data Display: Using tables to display fetched data and implementing pagination for better user experience.
  • API Integration: Learning how to interact with external APIs and handle JSON responses.

By working through this project, you’ll gain a deeper understanding of these concepts and be better prepared for more advanced web development challenges. Happy coding!


This content originally appeared on DEV Community and was authored by mibii


Print Share Comment Cite Upload Translate Updates
APA

mibii | Sciencx (2024-07-29T00:35:38+00:00) Building a React App to Fetch and Display BTC Unspent Outputs: A Beginner’s Guide. Retrieved from https://www.scien.cx/2024/07/29/building-a-react-app-to-fetch-and-display-btc-unspent-outputs-a-beginners-guide/

MLA
" » Building a React App to Fetch and Display BTC Unspent Outputs: A Beginner’s Guide." mibii | Sciencx - Monday July 29, 2024, https://www.scien.cx/2024/07/29/building-a-react-app-to-fetch-and-display-btc-unspent-outputs-a-beginners-guide/
HARVARD
mibii | Sciencx Monday July 29, 2024 » Building a React App to Fetch and Display BTC Unspent Outputs: A Beginner’s Guide., viewed ,<https://www.scien.cx/2024/07/29/building-a-react-app-to-fetch-and-display-btc-unspent-outputs-a-beginners-guide/>
VANCOUVER
mibii | Sciencx - » Building a React App to Fetch and Display BTC Unspent Outputs: A Beginner’s Guide. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/07/29/building-a-react-app-to-fetch-and-display-btc-unspent-outputs-a-beginners-guide/
CHICAGO
" » Building a React App to Fetch and Display BTC Unspent Outputs: A Beginner’s Guide." mibii | Sciencx - Accessed . https://www.scien.cx/2024/07/29/building-a-react-app-to-fetch-and-display-btc-unspent-outputs-a-beginners-guide/
IEEE
" » Building a React App to Fetch and Display BTC Unspent Outputs: A Beginner’s Guide." mibii | Sciencx [Online]. Available: https://www.scien.cx/2024/07/29/building-a-react-app-to-fetch-and-display-btc-unspent-outputs-a-beginners-guide/. [Accessed: ]
rf:citation
» Building a React App to Fetch and Display BTC Unspent Outputs: A Beginner’s Guide | mibii | Sciencx | https://www.scien.cx/2024/07/29/building-a-react-app-to-fetch-and-display-btc-unspent-outputs-a-beginners-guide/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.