简体   繁体   English

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

[英]How to save Redux Store as a downloaded file and then load it back?

I have a web app which has a notion of projects. 我有一个带有项目概念的Web应用程序。 I am using react , react-redux and react-persist with localForage as the persist target. 我正在将reactreact-reduxreact-persistlocalForage用作持久目标。

I am now trying to implement project save and project load functionality, and the entire Redux State serves as a project file. 我现在正在尝试实现项目保存项目加载功能,并且整个Redux状态都用作项目文件。 The project file should be saved to disk as a user download. 项目文件应作为用户下载文件保存到磁盘。 And/or any cloud file storage service. 和/或任何云文件存储服务。

The saving part is trivial, just take the store, serialize to JSON and plop it to the user for download. 保存部分微不足道,只需将商店存储起来,序列化为JSON并将其放到用户那里进行下载即可。

The loading is a little bit trickier, my ReactDOM.render is fairly usual. 加载有点棘手,我的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')
)

The configureStore() looks up if there is already a store created and returns it, otherwise it creates a new store. 如果已经创建了商店,则configureStore()查找并返回它,否则它将创建一个新商店。

For the load procedure, I was thinking something like this would do 对于加载过程,我在想这样的事情

  1. Load JSON from user and parse 从用户加载JSON并解析
  2. Clear localForage (as it would overwrite the initalState) 清除localForage(因为它将覆盖initalState)
  3. Recreate store, with initialState from the user submitted file 使用用户提交的文件中的initialState重新创建商店
  4. Call ReactDOM.render() again 再次调用ReactDOM.render()

Is there a better way, perhaps built-in load methods into redux and redux-persist which I missed in the docs? 有没有更好的方法,也许是我在文档中错过的reduxredux-persist内置的加载方法?

This is how I solved it, it's not the most elegant and requires registering callbacks on store reload, but it works. 这就是我解决的方法,它不是最优雅的方法,需要在商店重新加载时注册回调,但是它可以工作。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM