在react中使用 indexDb的方法
如何在react中使用 indexDb
下載依賴
npm install localforage
接下來(lái)像使用 localstore一樣使用它
import React, { useEffect } from 'react';
import localForage from 'localforage';
const App = () => {
useEffect(() => {
// 保存數(shù)據(jù)
async function storeData() {
try {
await localForage.setItem('user', { id: 1, name: 'John Doe' });
// 讀取數(shù)據(jù)
const userData = await localForage.getItem('user');
console.log(userData);
} catch (err) {
// 錯(cuò)誤處理
console.error(err);
}
}
storeData();
}, []);
return (
<div>
<h1>Welcome to IndexedDB with localForage</h1>
</div>
);
};
export default App;擴(kuò)展:前端離線存儲(chǔ)能力:如何在 React 中巧妙運(yùn)用IndexedDB
前端離線存儲(chǔ)能力:如何在 React 中巧妙運(yùn)用IndexedDB
前言
當(dāng)我們開發(fā)復(fù)雜的Web應(yīng)用時(shí),常常需要在客戶端存儲(chǔ)大量數(shù)據(jù)。你可能聽過(guò) localStorage或者 sessionStorage,但它們?cè)诖鎯?chǔ)空間和功能上都有限。而今天我們要聊的,是一個(gè)功能更強(qiáng)大的技術(shù):IndexedDB。
IndexedDB 是什么
IndexedDB是一個(gè)運(yùn)行在瀏覽器中的非關(guān)系型數(shù)據(jù)庫(kù)。它讓你能夠存儲(chǔ)大量的數(shù)據(jù),并具有高性能的查詢能力。不像localStorage只能存儲(chǔ)字符串,IndexedDB可以存儲(chǔ)各種類型的數(shù)據(jù),比如文件、Blob,以及你可以想到的其他各種類型。
IndexedDB 的能力
- 存儲(chǔ)大數(shù)據(jù)量: 它可以存儲(chǔ)比
localStorage更多的數(shù)據(jù),而且沒有固定的大小限制,往往是根據(jù)用戶磁盤大小的一定百分比。 - 復(fù)雜數(shù)據(jù)存儲(chǔ): 能夠存儲(chǔ)更加復(fù)雜的數(shù)據(jù)類型。
- 查詢性能優(yōu)越: IndexedDB支持索引,你可以建立索引快速檢索數(shù)據(jù),而不用遍歷整個(gè)數(shù)據(jù)庫(kù)。
- 離線應(yīng)用程序: 在用戶沒有網(wǎng)的時(shí)候,應(yīng)用還是可以訪問(wèn)到之前存儲(chǔ)的數(shù)據(jù)。
- 事務(wù)支持: IndexedDB支持事務(wù),你可以進(jìn)行復(fù)雜的數(shù)據(jù)操作,而且還有回滾的能力。
- 異步: 所有操作都是異步的,這也意味著它不會(huì)阻塞你的UI線程,用戶體驗(yàn)更好。
在 React 項(xiàng)目中使用 IndexedDB
好,現(xiàn)在我們知道了IndexedDB是個(gè)好東西,那如何在React中使用它呢?
這篇文章會(huì)介紹使用IndexedDB的兩種方式。
一、原生方式
我們來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的React hook來(lái)展示如何使用原生的IndexedDB API。
import { useEffect, useState } from 'react';
const useIndexedDB = (dbName, storeName) => {
const [db, setDb] = useState(null);
useEffect(() => {
const request = indexedDB.open(dbName, 1);
request.onerror = (event) => {
console.error('Database error:', event.target.errorCode);
};
request.onsuccess = (event) => {
setDb(event.target.result);
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
db.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true });
};
}, [dbName, storeName]);
const addData = (data) => {
const transaction = db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);
store.add(data);
};
return [db, addData];
};這個(gè)Hook非?;A(chǔ),它可以打開數(shù)據(jù)庫(kù),并允許你向數(shù)據(jù)庫(kù)中添加數(shù)據(jù)。
二、使用localForage
現(xiàn)在讓我們看看如何使用 localForage——一個(gè)快速簡(jiǎn)便的本地存儲(chǔ)庫(kù),以更簡(jiǎn)潔的方式使用IndexedDB。首先,你需要安裝 localForage:
npm install localforage
現(xiàn)在你可以用它來(lái)簡(jiǎn)化IndexedDB的操作了:
import localForage from 'localforage';
localForage.setItem('somekey', 'somevalue')
.then(() => {
return localForage.getItem('somekey');
})
.then((value) => {
// 這里是我們的數(shù)據(jù)
console.log(value);
})
.catch((err) => {
// 出錯(cuò)了!
console.error(err);
});localForage.setItem()和 localForage.getItem()都返回Promise,這讓它們可以很方便地與async/await一起使用。
import React, { useEffect } from 'react';
import localForage from 'localforage';
const App = () => {
useEffect(() => {
// 保存數(shù)據(jù)
async function storeData() {
try {
await localForage.setItem('user', { id: 1, name: 'John Doe' });
// 讀取數(shù)據(jù)
const userData = await localForage.getItem('user');
console.log(userData);
// => {id: 1, name: "John Doe"}
} catch (err) {
// 錯(cuò)誤處理
console.error(err);
}
}
storeData();
}, []);
return (
<div>
<h1>Welcome to IndexedDB with localForage</h1>
</div>
);
};
export default App;在這個(gè)例子中,我們創(chuàng)建了一個(gè)名為 App的React組件,在組件的 useEffect Hook中,我們寫了一個(gè)名為 storeData的 async函數(shù)來(lái)異步交互IndexedDB。我們先使用 setItem方法向IndexedDB中存入數(shù)據(jù),然后用 getItem讀取這些數(shù)據(jù),并把它們打印出來(lái)。
localForage支持回調(diào)和 Promise形式的API,這使得它非常容易在現(xiàn)代JavaScript或TypeScript應(yīng)用程序中使用。它也會(huì)自動(dòng)根據(jù)瀏覽器的支持情況后退到使用WebSQL或localStorage,這為你的應(yīng)用程序提供了更好的兼容性。
實(shí)戰(zhàn)
接下來(lái)讓我們?cè)囍鴺?gòu)建一個(gè)小型的待辦事項(xiàng)應(yīng)用,這個(gè)應(yīng)用將會(huì)使用React和IndexedDB原生API來(lái)存儲(chǔ)數(shù)據(jù)。
第一步:創(chuàng)建一個(gè)IndexedDB數(shù)據(jù)庫(kù)和對(duì)象存儲(chǔ)
創(chuàng)建React應(yīng)用的入口文件 App.js并編寫以下內(nèi)容:
import React, { useState, useEffect } from 'react';
function App() {
const [db, setDb] = useState(null);
const [todos, setTodos] = useState([]);
const [task, setTask] = useState('');
useEffect(() => {
let request = indexedDB.open('todoDB', 1);
request.onerror = (e) => {
console.log('Error opening db', e);
};
request.onsuccess = (e) => {
setDb(e.target.result);
};
request.onupgradeneeded = (e) => {
let db = e.target.result;
let store = db.createObjectStore('todos', { keyPath: 'id', autoIncrement: true });
store.createIndex('task', 'task', { unique: false });
};
}, []);
// ...后續(xù)內(nèi)容將會(huì)增加到這里...
return (
<div>
<h1>Todo App with IndexedDB</h1>
{/* 待辦事項(xiàng)表單和列表展示將會(huì)在這里添加 */}
</div>
);
}
export default App;第二步:實(shí)現(xiàn)添加和顯示待辦事項(xiàng)的功能
現(xiàn)在,我們?cè)诮M件內(nèi)實(shí)現(xiàn)添加新的待辦事項(xiàng)到IndexedDB中和從數(shù)據(jù)庫(kù)中讀取待辦事項(xiàng)列表的功能。
更新 App.js,添加以下內(nèi)容:
// ...之前的代碼...
function addTodo() {
const transaction = db.transaction(['todos'], 'readwrite');
const store = transaction.objectStore('todos');
let request = store.add({ task });
request.onsuccess = () => {
console.log('Task added');
setTask(''); // 清空輸入
loadTodos(); // 重新加載待辦事項(xiàng)列表
};
}
function loadTodos() {
let transaction = db.transaction(['todos'], 'readonly');
let store = transaction.objectStore('todos');
let request = store.openCursor();
let todos = [];
request.onsuccess = (e) => {
let cursor = e.target.result;
if (cursor) {
todos.push(cursor.value);
cursor.continue();
} else {
setTodos(todos);
}
};
}
// 確保數(shù)據(jù)被加載
useEffect(() => {
if (db) {
loadTodos();
}
}, [db]);
// ...之前的代碼...
return (
<div>
{/* 其他代碼 */}
<input type="text" value={task} onChange={(e) => setTask(e.target.value)} />
<button onClick={addTodo}>Add Task</button>
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.task}</li>
))}
</ul>
</div>
);
// ...之前的代碼...以上代碼完成了以下功能:
- 通過(guò)
useEffect鉤子創(chuàng)建或打開一個(gè)名為todoDB的IndexedDB數(shù)據(jù)庫(kù),如果不存在,就會(huì)創(chuàng)建一個(gè)名叫todos的對(duì)象存儲(chǔ)。 - 使用
addTodo函數(shù)來(lái)將新任務(wù)添加進(jìn)數(shù)據(jù)庫(kù)。 - 使用
loadTodos函數(shù)查詢IndexedDB中的所有待辦事項(xiàng),并將它們?cè)O(shè)置到組件狀態(tài)中,以便可以在React組件中顯示這些待辦事項(xiàng)。 - 提供了一個(gè)簡(jiǎn)單的表單,可以輸入新的待辦事項(xiàng)并添加到列表中。
此時(shí),我們已經(jīng)擁有了一個(gè)可以使用IndexedDB存儲(chǔ)數(shù)據(jù)的基本的待辦事項(xiàng)應(yīng)用。當(dāng)然,實(shí)際應(yīng)用中還需要很多增強(qiáng),比如錯(cuò)誤處理、用戶輸入驗(yàn)證以及待辦事項(xiàng)的刪除和編輯功能等。但這個(gè)例子足以說(shuō)明如何在React中直接使用IndexedDB,以及開發(fā)可以持久存儲(chǔ)用戶數(shù)據(jù)的Web應(yīng)用程序。
結(jié)論
IndexedDB的確是一種功能強(qiáng)大的工具,尤其適合那些需要存儲(chǔ)和操作大量和/或復(fù)雜數(shù)據(jù)的Web應(yīng)用程序。不過(guò),記住它的API并不像localStorage那么簡(jiǎn)單直接,所以在大多數(shù)情況下,使用 localForage等庫(kù)可以大大簡(jiǎn)化這個(gè)過(guò)程。
到此這篇關(guān)于如何在react中使用 indexDb的文章就介紹到這了,更多相關(guān)react使用 indexDb內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用react-color實(shí)現(xiàn)前端取色器的方法
本文通過(guò)代碼給大家介紹了使用react-color實(shí)現(xiàn)前端取色器的方法,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-11-11
詳解React Native網(wǎng)絡(luò)請(qǐng)求fetch簡(jiǎn)單封裝
本篇文章主要介紹了詳解React Native網(wǎng)絡(luò)請(qǐng)求fetch簡(jiǎn)單封裝,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
ReactJs實(shí)現(xiàn)樹形結(jié)構(gòu)的數(shù)據(jù)顯示的組件的示例
本篇文章主要介紹了ReactJs實(shí)現(xiàn)樹形結(jié)構(gòu)的數(shù)據(jù)顯示的組件的示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-08-08
React-redux?中useSelector使用源碼分析
在一個(gè) action 被分發(fā)(dispatch) 后,useSelector() 默認(rèn)對(duì) select 函數(shù)的返回值進(jìn)行引用比較 ===,并且僅在返回值改變時(shí)觸發(fā)重渲染,,這篇文章主要介紹了React-redux?中useSelector使用,需要的朋友可以參考下2023-10-10
React css-in-js基礎(chǔ)介紹與應(yīng)用
隨著React、Vue等支持組件化的MVVM前端框架越來(lái)越流行,在js中直接編寫css的技術(shù)方案也越來(lái)越被大家所接受。為什么前端開發(fā)者們更青睞于這些css-in-js的方案呢,下面帶你了解它2022-09-09

