如何将Redux Store保存为下载文件,然后再加载回去?

时间:2018-09-23 12:00:27

标签: reactjs redux react-redux redux-persist

我有一个带有项目概念的Web应用程序。我将reactreact-redux用作react-persistlocalForage作为持久目标。

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

保存的部分微不足道,只需将商店,序列化为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()

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

1 个答案:

答案 0 :(得分:0)

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

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 }
}