You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:55:17