首页 > 解决方案 > 如何将 Redux Store 保存为下载的文件,然后将其加载回来?

问题描述

我有一个具有项目概念的网络应用程序。我正在使用react,react-reduxreact-persistwithlocalForage作为持久目标。

我现在正在尝试实现项目保存项目加载功能,整个 Redux State 都作为一个项目文件。项目文件应作为用户下载保存到磁盘。和/或任何云文件存储服务。

保存部分是微不足道的,只需将存储,序列化为 JSON,然后将其发送给用户以供下载。

加载有点棘手,我ReactDOM.render是相当平常的。

const {store, persistor} = configureStore()
ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <Router>
        <Route path={`${process.env.PATH}/`} component={App} />
      </Router>
    </PersistGate>
  </Provider>,
  document.getElementById('app')
)

如果已经创建了一个商店,configureStore()则查找并返回它,否则它会创建一个新商店。

对于加载过程,我在想这样的事情会做

  1. 从用户加载 JSON 并解析
  2. 清除 localForage(因为它会覆盖 initalState)
  3. 使用用户提交的文件中的 initialState 重新创建商店
  4. 再次调用 ReactDOM.render()

redux有没有更好的方法,也许是我在文档中错过的内置加载方法redux-persist

标签: reactjsreduxreact-reduxredux-persist

解决方案


这就是我解决它的方法,它不是最优雅的,并且需要在商店重新加载时注册回调,但它可以工作。

const createNewStore = (initialState = undefined) => {
  const persistConfig = { key: 'root', storage: localForage }
  store = createStore(
    persistReducer(persistConfig, reducers),
    initialState,
    createMiddleware()
  )
  persistor = persistStore(store)
}

const loadState = (state) => {
  createNewStore(state)
  callbacks.forEach(callback => {
    callback()
  })
}

export const loadStore = (json) => {
  return new Promise((resolve, reject) => {
    let state

    try {
      state = JSON.parse(json)
    } catch (err) {
      return reject(err)
    }

    if (!persistor) {
      return resolve(loadState(state))
    }
    persistor.purge().then(() => {
      return resolve(loadState(state))
    }).catch(() => {
      return resolve(loadState(state))
    })
  })
}

const getStore = (storeReplaceCallback = null) => {
  if (storeReplaceCallback) {
    callbacks.push(storeReplaceCallback)
  }

  if (!store) {
    createNewStore()
  }

  return { store, persistor }
}

推荐阅读