Today, you’ll learn how to use IndexedDB for local data storage in your Progressive Web App (PWA). IndexedDB provides a way to store large amounts of structured data on the client-side, allowing your app to store and retrieve data even without a network connection.
What You Will Do Today:
- Understand IndexedDB and why it’s useful for PWAs.
- Set up IndexedDB using the
idb
library. - Create, read, update, and delete data in IndexedDB.
- Use IndexedDB to cache data for offline access.
Step 1: Understanding IndexedDB
IndexedDB is a low-level API for storing significant amounts of structured data, including files and blobs. Unlike local storage, IndexedDB supports more complex queries, multiple data types, and large storage capacities. IndexedDB is especially useful in PWAs for caching data, such as API responses, for offline use.
Step 2: Setting Up IndexedDB with idb
The idb
library provides a simpler way to interact with IndexedDB. Let’s install it and set up a database.
- Install
idb
:
npm install idb
- Create a file named
db.js
in yoursrc
folder to set up the IndexedDB database:
// src/db.js
import { openDB } from 'idb';
const DATABASE_NAME = 'MyPWA';
const DATABASE_VERSION = 1;
const STORE_NAME = 'items';
export async function initDB() {
return openDB(DATABASE_NAME, DATABASE_VERSION, {
upgrade(db) {
if (!db.objectStoreNames.contains(STORE_NAME)) {
db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true });
}
},
});
}
export async function addItem(item) {
const db = await initDB();
const tx = db.transaction(STORE_NAME, 'readwrite');
await tx.store.add(item);
await tx.done;
}
export async function getAllItems() {
const db = await initDB();
return db.getAll(STORE_NAME);
}
export async function deleteItem(id) {
const db = await initDB();
const tx = db.transaction(STORE_NAME, 'readwrite');
await tx.store.delete(id);
await tx.done;
}
Explanation of Code:
- initDB: Initializes the IndexedDB database. If the
items
object store doesn’t exist, it’s created with an auto-incrementingid
. - addItem: Adds an item to the
items
store. - getAllItems: Retrieves all items from the
items
store. - deleteItem: Deletes an item by
id
.
Step 3: Adding and Retrieving Data from IndexedDB
Let’s create a component to add, retrieve, and display items stored in IndexedDB.
- Create a new file called
Items.js
in thesrc
folder:
// src/Items.js
import React, { useState, useEffect } from 'react';
import { addItem, getAllItems, deleteItem } from './db';
function Items() {
const [items, setItems] = useState([]);
const [inputValue, setInputValue] = useState('');
useEffect(() => {
fetchItems();
}, []);
const fetchItems = async () => {
const storedItems = await getAllItems();
setItems(storedItems);
};
const handleAddItem = async () => {
if (inputValue.trim()) {
await addItem({ name: inputValue });
setInputValue('');
fetchItems();
}
};
const handleDeleteItem = async (id) => {
await deleteItem(id);
fetchItems();
};
return (
<div>
<h2>Items</h2>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="Add new item"
/>
<button onClick={handleAddItem}>Add Item</button>
<ul>
{items.map((item) => (
<li key={item.id}>
{item.name} <button onClick={() => handleDeleteItem(item.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}
export default Items;
Explanation of Code:
- fetchItems: Retrieves all items from IndexedDB and updates the component’s state.
- handleAddItem: Adds a new item to IndexedDB and refreshes the list.
- handleDeleteItem: Deletes an item from IndexedDB and refreshes the list.
Step 4: Integrating the Component into the App
- Open
App.js
and import theItems
component to display it in the app:
import React from 'react';
import Items from './Items';
function App() {
return (
<div>
<h1>My PWA with IndexedDB</h1>
<Items />
</div>
);
}
export default App;
Step 5: Testing IndexedDB for Offline Access
- Start the app using
npm start
. - Add several items using the input box and the “Add Item” button.
- Open Developer Tools in your browser, go to Application > IndexedDB, and inspect the
MyPWA
database. You should see the items you added. - Switch to offline mode in Developer Tools > Network > Offline and refresh the app. You should still see the items listed, as they are stored in IndexedDB.
Summary
Today, you used IndexedDB to store data locally in your PWA, allowing you to retrieve data even while offline. This feature adds robustness to your PWA by maintaining data availability regardless of network conditions.
Tomorrow, you’ll add push notifications to your PWA for user engagement.