Firebase Redux状态架构:替代本地状态及未登录场景适配方案咨询
方案解答
核心问题答疑
Firebase无法完全替代所有本地状态,也不会让你损失Flux状态管理的优势
- 类似弹窗开关、表单临时输入、页面滚动位置这类UI临时状态,本身不需要同步到云端,存在本地状态管理是更合理的选择
- 你在用的react-redux-firebase本身就是基于Redux实现的,核心逻辑就是把Firebase的云端业务数据自动同步到本地Redux Store中,你依然可以使用单向数据流、action可追溯、时间旅行调试等所有Flux架构的优势,不需要把云端状态和本地状态割裂开来
不需要额外维护一套独立的本地状态管理体系,只要把登录态判断逻辑下沉到架构底层,上层业务代码可以完全复用同一套逻辑,不会额外增加开发成本
具体架构实现方案
第一步:统一数据源入口
所有上层业务组件只从Redux Store的同一份字段取数,不需要在组件内判断登录状态:
- 登录状态下,react-redux-firebase会自动把云端数据同步到Store的对应字段(例如
entries) - 未登录状态下,本地产生的业务数据也存入Store的同一个
entries字段 - 上层组件直接读取
store.entries进行渲染即可,不需要再写三元判断逻辑,优化后的数据读取代码如下:
// 组件内只需要从统一的Store入口取数 const { entries } = useSelector(state => state) entries.map(/* 渲染逻辑 */)
第二步:封装统一Action层
把登录态判断逻辑封装在Action内部,上层组件只需要调用同一个Action,不需要感知底层实现差异。以删除操作为例,封装Thunk Action如下:
export const deleteEntry = (id) => async (dispatch, getState) => { const { userSignedIn } = getState().auth if (userSignedIn) { // 登录状态调用Firebase接口,库会自动同步更新Store内的entries数据 await firebase.remove(`entries/${id}`) } else { // 未登录状态直接修改本地Store数据 dispatch({ type: 'DELETE_ENTRY', payload: id }) } }
上层组件的触发逻辑可以简化为统一调用,不需要做登录态判断:
<button onClick={() => dispatch(deleteEntry(id))}> Delete </button>
第三步:可选的登录数据同步逻辑
如果需要保留未登录时用户产生的业务数据,可以在用户首次登录成功后,批量把本地Store中存储的未同步数据上传到Firebase,上传完成后后续就依赖库的自动同步能力即可,用户全程无感知。
额外优化建议
- 所有Firebase相关的交互逻辑都统一封装在Action或者独立的Service层,不要散落在业务组件内,后续如果调整云端服务也不需要修改上层业务代码
- 如果需要离线使用能力,可以直接开启Firebase自带的离线持久化能力,登录状态下断网时的操作会自动缓存,联网后自动同步,上层代码不需要做任何修改
内容的提问来源于stack exchange,提问作者user14810677
相关产品推荐
相关产品推荐

