Generate QR Codes in React
Want to create customisable QR codes on your site? Similar to what sites like freeqrgen.net are doing? Well wonder no more, I will go into the process of installing the pwoerful package qrcode.react and give some examples of how to integrate this tool into your React toolbelt.
qrcode.react have a fantastic demo where you can play around with the different props and settings that the library offers. Play and see what’s possible.
If you’d rather watch how it’s done than read, I have a code-walkthrough of creating a React QR Code application.
If you’re starting from a blank slate, follow along by first creating a react app
npx create-react-app qr-gen --template typescript
Now first step to using this library is to download it!
NPM:
npm install qrcode.react
PNPM:
pnpm add qrcode.react
YARN:
yarn add qrcode.react
Step one wasn’t so bad… now let’s create us a QR component that will render the QR code we’re generating to the FE so we can see our magic come to life before our eyes:
QrCode.tsx
import { QRCodeSVG } from 'qrcode.react'
export default function QrCode() {
return (
<QrCode
value="https://http://devdailyhub.com/"
size={128}
bgColor={'#FFF'}
fgColor={'#000'}
/>
)
}
Now wherever you want to display the QR code in your project, simply import and return the component App.tsx
:
import QrCode from './QrCode' // <--- Make this path point to wherever you saved the QrCode component
export default function App() {
return (
<div className="App">
<header className="App-header">
<h1>Amazing QR Gen App</h1>
</header>
{/* some other random content that's top notch */}
<QrCode />
</div>
)
}
Easy as pie, we got ourselves a QR code, give it a scan to test it out!
That’s all well and good, but it’s not that exciting really is it? A plain, black and white QR code with no character… We can do better than that!
We need to update the default styles to stop the header taking up ALL of the height now, in App.css
make sure your .App-header
class looks like this:
.App-header {
background-color: #282c34;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
margin-bottom: 2rem;
}
Let’s create us a form to capture some config options that’s take our QR Code to the NEXT LEVEL 🚀!
First off, we want to create some state so we can update some values and send them to our QrCode
component.
In App.tsx
:
export default function App() {
import { useState }, React from "react"
const [url, setUrl] = useState('');
const [size, setSize] = useState(128);
const [bgColour, setBgColour] = useState('#FFF');
const [fgColour, setFgColour] = useState('#000');
return (
// ... our current code
)
}
Okay now let’s move onto creating some essential Form Components that we can re-use, we will add a new folder and file called types/types.ts
:
types.ts
export interface ICoreInput {
type?: 'text' | 'number'
id: string
label: string
}
TextInput.tsx
import React, { ChangeEvent, Dispatch, SetStateAction } from 'react'
import { ICoreInput } from '../types/types'
interface ITextInput<T extends string | number> extends ICoreInput {
value: T
setValue: Dispatch<SetStateAction<T>>
max?: number
min?: number
}
export default function TextInput<T extends string | number>({
id,
label,
value,
setValue,
type,
max,
min,
}: ITextInput<T>) {
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
if (type === 'number') {
setValue(Number(e.target.value) as T)
} else {
setValue(e.target.value as T)
}
}
return (
<div>
<label htmlFor={id}>{label}: </label>
<input
id={id}
name={id}
value={value}
type={type || 'text'}
onChange={handleChange}
max={max}
min={min}
/>
</div>
)
}
QRConfigForm.tsx
import React, { Dispatch, SetStateAction } from 'react'
import TextInput from './TextInput'
interface IQrConfigForm {
url: string
setUrl: Dispatch<SetStateAction<string>>
size: number
setSize: Dispatch<SetStateAction<number>>
bgColour: string
setBgColour: Dispatch<SetStateAction<string>>
fgColour: string
setFgColour: Dispatch<SetStateAction<string>>
}
export default function QrConfigForm({
url,
setUrl,
size,
setSize,
bgColour,
setBgColour,
fgColour,
setFgColour,
}: IQrConfigForm) {
return (
<div className="qr-config-form-container">
<TextInput<string>
id="url"
label="QR URL"
setValue={setUrl}
value={url}
/>
<TextInput<number>
id="size"
label="QR Size"
setValue={setSize}
value={size}
type="number"
min={1}
max={10000}
/>
<TextInput<string>
id="background-colour"
value={bgColour}
setValue={setBgColour}
label="Background Colour"
/>
<TextInput<string>
id="foreground-colour"
value={fgColour}
setValue={setFgColour}
label="Foreground Colour"
/>
</div>
)
}
Now we can import and pass the values we set in this form from our Main.tsx
down to our QrCode.tsx
component:
First off let’s set-up the interface and QrCode component so it’s ready to accept our form data as props:
QrCode.tsx
import { QRCodeSVG } from 'qrcode.react'
interface IQrCode {
url: string
size: number
bgColor: string
fgColor: string
}
export default function QrCode({ url, size, bgColor, fgColor }) {
return (
<QrCode
value={url ?? 'https://devdailyhub.com/'}
size={size ?? 128}
bgColor={bgColor ?? '#FFF'}
fgColor={fgColor ?? '#000'}
/>
)
}
Now we can pass the state down to the QrCode
component:
Main.tsx
import { QRCodeSVG } from 'qrcode.react'
interface IQrCode {
url: string
size: number
bgColour: string
fgColour: string
}
export default function QrCode({ bgColour, fgColour, size, url }: IQrCode) {
return (
<QRCodeSVG
value={url ?? 'https://devdailyhub.com'}
size={size ?? 128}
bgColor={bgColour ?? '#FFF'}
fgColor={fgColour ?? '#000'}
/>
)
}
It looks so basic, it’s pretty horrible, this isn’t a guide on how to make the most sexy web app however, so just a few basic styles to stop our eyes from falling out… Add this class to the App.css
file to spruce up the form a little:
.qr-config-form-container {
display: flex;
flex-direction: column;
gap: 1rem;
font-size: 1.5em;
margin-bottom: 1rem;
}
Much more interesting! Now we can update the URL our QR code points to, we can update the size and both the foreground & background colours!
There’s still a load of improvements we can make however, typing in a colour is kinda lame, how if we use a colour picker instead? Also the way it re-renders every-time we change the URL is a bit dodgy looking.
You can see a fully working version of this with the above improvements at freeqrgen.net
If you’d like me to go through any of the above do let me know at dev@aidanlowson.com
Do Subscribe to my YouTube channel where I’ll be doing more guides, code-through and other programming related content subscribe here to keep up-to-date.