How to Generate QR Codes in React

Build a reusable QR code generator component for your React application using the QR Code API and React hooks.

📅 Updated December 2025 ⏱️ 10 min read

In this tutorial, you'll build a production-ready QR code generator component for React. We'll use React hooks for state management and the QR Code API for generation.

What You'll Build

Basic QR Code Component

Let's start with a simple component that generates and displays a QR code:

QRCode.jsx
import { useState, useEffect } from 'react';

export function QRCode({ data, size = 200 }) {
  const [qrUrl, setQrUrl] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const generateQR = async () => {
      try {
        setLoading(true);
        const response = await fetch('https://www.qrcodeapi.io/api/generate', {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${process.env.REACT_APP_QR_API_KEY}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ data, size, format: 'png' })
        });

        if (!response.ok) throw new Error('Failed to generate QR code');

        const blob = await response.blob();
        setQrUrl(URL.createObjectURL(blob));
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    if (data) generateQR();
  }, [data, size]);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return <img src={qrUrl} alt="QR Code" width={size} height={size} />;
}

Custom Hook: useQRCode

For better reusability, let's extract the logic into a custom hook:

useQRCode.js
import { useState, useEffect, useCallback } from 'react';

export function useQRCode(data, options = {}) {
  const {
    size = 200,
    format = 'png',
    color = '#000000',
    background = '#ffffff'
  } = options;

  const [qrUrl, setQrUrl] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const generate = useCallback(async () => {
    if (!data) return;
    
    setLoading(true);
    setError(null);

    try {
      const response = await fetch('https://www.qrcodeapi.io/api/generate', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.REACT_APP_QR_API_KEY}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ data, size, format, color, background })
      });

      if (!response.ok) {
        const err = await response.json();
        throw new Error(err.message || 'Generation failed');
      }

      const blob = await response.blob();
      
      // Clean up previous URL
      if (qrUrl) URL.revokeObjectURL(qrUrl);
      
      setQrUrl(URL.createObjectURL(blob));
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [data, size, format, color, background]);

  useEffect(() => {
    generate();
  }, [generate]);

  return { qrUrl, loading, error, regenerate: generate };
}

Complete Component with Download

Here's a full-featured component with download functionality:

QRCodeGenerator.jsx
import { useState } from 'react';
import { useQRCode } from './useQRCode';

export function QRCodeGenerator() {
  const [input, setInput] = useState('');
  const [data, setData] = useState('');
  const { qrUrl, loading, error } = useQRCode(data, { size: 300 });

  const handleGenerate = () => setData(input);

  const handleDownload = () => {
    if (!qrUrl) return;
    const link = document.createElement('a');
    link.href = qrUrl;
    link.download = 'qrcode.png';
    link.click();
  };

  return (
    <div className="qr-generator">
      <input
        type="text"
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="Enter URL or text"
      />
      <button onClick={handleGenerate} disabled={!input || loading}>
        {loading ? 'Generating...' : 'Generate QR Code'}
      </button>

      {error && <p className="error">{error}</p>}

      {qrUrl && (
        <div className="qr-result">
          <img src={qrUrl} alt="QR Code" />
          <button onClick={handleDownload}>Download</button>
        </div>
      )}
    </div>
  );
}

Environment Setup

Store your API key safely in environment variables:

.env
REACT_APP_QR_API_KEY=your_api_key_here

Best Practices

Ready to Build Your React QR Generator?

Get your free API key and start building today.

Get Your Free API Key