feat: 优化数据操作体验,使用乐观更新
- 保存/删除操作立即更新UI,无需等待API - 避免页面闪烁和数据重新加载 - API失败时自动恢复数据
This commit is contained in:
parent
4a16ce7707
commit
0dccb698fe
@ -125,12 +125,16 @@ function App() {
|
||||
}
|
||||
if (editingCategory) {
|
||||
await categoryApi.update(editingCategory.id, payload)
|
||||
// 乐观更新:直接修改列表中的项
|
||||
setCategories(categories.map(c => c.id === editingCategory.id ? { ...c, ...payload } : c))
|
||||
} else {
|
||||
await categoryApi.create(payload)
|
||||
const res = await categoryApi.create(payload)
|
||||
// 乐观更新:添加到列表
|
||||
const newCat = res.data
|
||||
setCategories([...categories, newCat])
|
||||
}
|
||||
setCategoryForm({ name: '', icon: 'folder', color: '#667eea', sort_order: 0 })
|
||||
setEditingCategory(null)
|
||||
loadData()
|
||||
} catch (e) { console.error(e) } finally {
|
||||
setSaving(false)
|
||||
}
|
||||
@ -138,11 +142,18 @@ function App() {
|
||||
|
||||
const deleteCategory = async (id) => {
|
||||
if (!confirm('确定删除该分类?该分类下的网站将变为未分类状态。')) return
|
||||
// 乐观删除:先从UI移除
|
||||
const catName = categories.find(c => c.id === id)?.name
|
||||
setCategories(categories.filter(c => c.id !== id))
|
||||
// 网站也更新为未分类
|
||||
setWebsites(websites.map(s => s.category_id === id ? { ...s, category_id: null, category: null } : s))
|
||||
if (selectedCategory === id) setSelectedCategory(null)
|
||||
try {
|
||||
await categoryApi.delete(id)
|
||||
if (selectedCategory === id) setSelectedCategory(null)
|
||||
} catch (e) {
|
||||
// 失败则恢复
|
||||
loadData()
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
// 保存网站
|
||||
@ -151,13 +162,17 @@ function App() {
|
||||
setSaving(true)
|
||||
try {
|
||||
const payload = { ...websiteForm, category_id: websiteForm.category_id || null }
|
||||
const catName = categories.find(c => c.id === websiteForm.category_id)?.name
|
||||
if (modal.data) {
|
||||
await websiteApi.update(modal.data.id, payload)
|
||||
// 乐观更新
|
||||
setWebsites(websites.map(s => s.id === modal.data.id ? { ...s, ...payload, category: catName ? { name: catName } : null } : s))
|
||||
} else {
|
||||
await websiteApi.create(payload)
|
||||
const res = await websiteApi.create(payload)
|
||||
const newSite = { ...res.data, category: catName ? { name: catName } : null }
|
||||
setWebsites([...websites, newSite])
|
||||
}
|
||||
closeModal()
|
||||
loadData()
|
||||
} catch (e) {} finally {
|
||||
setSaving(false)
|
||||
}
|
||||
@ -165,10 +180,13 @@ function App() {
|
||||
|
||||
const handleDeleteWebsite = async (id) => {
|
||||
if (!confirm('确定删除?')) return
|
||||
// 乐观删除
|
||||
setWebsites(websites.filter(s => s.id !== id))
|
||||
try {
|
||||
await websiteApi.delete(id)
|
||||
} catch (e) {
|
||||
loadData()
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
const toggleFavorite = async (site) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user