如何强制更新以应用Firestore帖子列表的动态排序规则变更?
核心问题
你当前的代码存在3个逻辑错误,修改forceUpdate默认值完全无法解决根本问题:
- 事件监听注册位置错误:你把
addEventListener放在selectPosts函数内部,每次调用该函数都会重复注册相同的监听事件,造成内存泄漏和逻辑异常 - 排序变更后没有重新拉取数据:下拉列表
change事件触发时,你只是修改了函数局部变量constraints,并没有主动重新调用selectPosts获取新排序的帖子数据,页面自然不会更新 - 局部变量无法持久保存排序规则:
constraints是selectPosts的内部局部变量,每次调用函数都会被重置为默认值,事件回调修改的值在函数执行完成后就失效了,下次调用还是用默认排序
修复方案
- 将下拉列表监听事件移到初始化逻辑中,仅注册一次,同时把当前选中的排序值作为全局/组件状态保存,不要依赖函数局部变量传值
- 下拉列表变更触发时,主动调用
selectPosts并传入forceUpdate=true,拿到返回的新排序数据后替换页面渲染用的帖子列表 - 调整
selectPosts内部逻辑,根据当前保存的排序状态生成constraints数组,不要在内部注册事件
修改后完整代码
初始化逻辑(仅执行一次)
// 全局/组件状态保存当前排序,1=最新发布,2=点赞最多 let currentSortType = 1 const hw = document.getElementById('dropDowmListID') // 监听事件只注册一次 hw.addEventListener('change', async function() { currentSortType = Number(hw.value) // 排序变更后主动拉取新数据,传入forceUpdate=true const newPostList = await selectPosts({}, true) // 此处将newPostList赋值给你页面渲染用的帖子列表变量,触发页面更新 // 原生JS就手动操作DOM更新,框架就给响应式变量赋值即可 })
调整后的selectPosts函数
async selectPosts (options = {}, forceUpdate = false) { const goodOrderByDir = 'desc' const dateOrderByDir = 'desc' const db = getFirestore() // 根据当前排序状态生成约束数组 let constraints = [] if (currentSortType === 1) { constraints = [orderBy('date', dateOrderByDir), orderBy('good', goodOrderByDir)] } else if (currentSortType === 2) { constraints = [orderBy('good', goodOrderByDir), orderBy('date', dateOrderByDir)] } if (forceUpdate) { this._lastSelectPostsOptions = {} } constraints.push(limit(pageSize)) const queryRef = query(collection(db, 'posts'), ...constraints) return Promise.all((await getDocs(queryRef)).docs.map(async item => { this._lastSelectPostsDoc = item return item.data() })) }
内容的提问来源于stack exchange,提问作者dkskfktldi
相关产品推荐
相关产品推荐

