Tauri应用启动时异步加载Redux预加载状态的解决方法
解决Tauri + Redux Toolkit异步加载preloadedState问题
核心问题分析
configureStore是同步函数,无法直接传入异步获取的preloadedState,因此需要将store的创建流程改为异步模式,在应用启动阶段先完成文件读取,再初始化store。
步骤1:重构store为异步创建函数
修改store.ts,将同步导出store改为异步创建函数,在内部完成文件读取逻辑:
import { configureStore } from '@reduxjs/toolkit'; import { readTextFile, exists, join } from '@tauri-apps/api/fs'; import { appLocalDataDir } from '@tauri-apps/api/path'; // 定义你的根reducer const rootReducer = { // ...你的reducers在这里 }; export async function createStore() { let preloadedState; try { // 获取应用本地数据目录 const appDataDir = await appLocalDataDir(); const storeFilePath = join(appDataDir, 'app-store.json'); // 先检查文件是否存在,避免读取不存在的文件报错 const fileExists = await exists(storeFilePath); if (fileExists) { const rawData = await readTextFile(storeFilePath); preloadedState = JSON.parse(rawData); } } catch (err) { console.error('加载持久化数据失败:', err); // 出错时使用默认状态,防止应用崩溃 preloadedState = undefined; } return configureStore({ reducer: rootReducer, preloadedState, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(filePersistenceMiddleware) }); }
步骤2:修改应用入口,等待store初始化
在应用入口文件(比如main.tsx)中,先调用异步的createStore完成初始化,再渲染应用:
import React from 'react'; import ReactDOM from 'react-dom/client'; import { Provider } from 'react-redux'; import App from './App'; import { createStore } from './store'; async function bootstrapApp() { const store = await createStore(); ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode> ); } bootstrapApp();
步骤3:更新持久化Middleware(替换localStorage)
将原来的localStorageMiddleware修改为写入文件的逻辑:
import { writeTextFile, join } from '@tauri-apps/api/fs'; import { appLocalDataDir } from '@tauri-apps/api/path'; export const filePersistenceMiddleware = store => next => async action => { const actionResult = next(action); // 每次状态更新后,写入文件 try { const appDataDir = await appLocalDataDir(); const storeFilePath = join(appDataDir, 'app-store.json'); await writeTextFile(storeFilePath, JSON.stringify(store.getState())); } catch (err) { console.error('保存状态到文件失败:', err); } return actionResult; };
其他持久化方案建议
- Redux Persist + 自定义Tauri存储引擎:Redux Persist是成熟的Redux持久化方案,你可以实现一个基于Tauri文件系统的存储适配器,替代默认的localStorage,利用它的状态迁移、序列化配置等功能,减少自定义代码量。
- SQLite数据库:如果你的数据结构复杂、需要查询操作,推荐使用Tauri的
tauri-plugin-sql插件,用SQLite存储数据,比JSON文件更适合复杂场景,数据完整性和查询性能更好。 - Tauri内置的localStorage:其实Tauri webview的localStorage本身就存储在应用数据目录下,若只是需要存储更多数据,JSON文件足够;但如果数据量极大或需要结构化操作,SQLite更合适。
内容的提问来源于stack exchange,提问作者Boguz
相关产品推荐
相关产品推荐

