如何在 Next.js 中持久化 redux 状态数据?

Posted

技术标签:

【中文标题】如何在 Next.js 中持久化 redux 状态数据?【英文标题】:How to persist redux state data in Next.js? 【发布时间】:2019-05-30 21:09:33 【问题描述】:

我最近用我的 Next.js 项目设置了 redux,现在我正在处理持久化 redux 数据,这样在每次页面刷新时,我都可以拥有持久化状态。所以我添加了 redux-persist 来处理这种情况,因为它是 react-redux 的最佳解决方案,但我不知道为什么它在 next.js 中也不能使用 next-redux-wrapper 或 withRedux 库。所以请帮我解决这个问题,是否存在类似 redux-persist 的东西?(虽然我不想要 cookie 的解决方案),如果是,那么请建议我参考示例,这将非常有帮助。提前谢谢...

我实际上是在尝试在每次页面刷新后保持 redux 状态,所以我也将 redux-persist 与 next-redux-wrapper 一起使用,但我遇到了错误

/store.js

    import  createStore, applyMiddleware  from 'redux'
    import  composeWithDevTools  from 'redux-devtools-extension'
    import thunkMiddleware from 'redux-thunk'
    import  persistReducer  from 'redux-persist';
    import storage from 'redux-persist/lib/storage';

    const persistConfig = 
      timeout: 0,
      key: 'root',
      storage,
    ;
    const persistedReducer = persistReducer(persistConfig, reducer);

    export default () => 
      return createStore(persistedReducer,
        composeWithDevTools(
          applyMiddleware(
            thunkMiddleware
          )
        ));
    ;

/_app.js

    import App,  Container  from 'next/app'
    import React from 'react'
    import  Provider  from 'react-redux'
    import withRedux from 'next-redux-wrapper';
    import  PersistGate  from 'redux-persist/integration/react';
    import  persistStore  from 'redux-persist';
    import store from '../store';

    class MyApp extends App 
      static async getInitialProps (Component, ctx) 
        return 
          pageProps: (Component.getInitialProps ? await Component.getInitialProps(ctx) : )
        ;
      

      render () 
        const  Component, pageProps, reduxStore  = this.props;
        const persistor = persistStore(store);
        return (
          <Container>
            <Provider store=store>
            <PersistGate loading=null persistor=persistor>
                <Component ...pageProps />
              </PersistGate>
            </Provider>
          </Container>
        )
      
    

我希望它会保持状态,但我收到这样的错误:“redux-persist failed to create sync storage.fall back to memory storage.TypeError: baseReducer is not a function”

【问题讨论】:

你为什么不按照next.js github推荐的例子。 github.com/zeit/next.js/tree/canary/examples/with-redux你应该用redux-persist导出你的_app类 我遵循了 zeit 在他们的文档中提供的相同示例,但我无法获得解决方案。顺便说一句,我不知道如何用 redux-persist man 导出 _app 类,你能帮我看看吗,我可以试试.. 【参考方案1】:

创建一个您自己的storage.js 文件。 将文件放在主项目文件夹中。 使用此代码...

import createWebStorage from "redux-persist/lib/storage/createWebStorage";

const createNoopStorage = () => 
  return 
    getItem(_key) 
      return Promise.resolve(null);
    ,
    setItem(_key, value) 
      return Promise.resolve(value);
    ,
    removeItem(_key) 
      return Promise.resolve();
    ,
  ;
;

const storage = typeof window !== "undefined" ? createWebStorage("local") : createNoopStorage();

export default storage;

转到在 Nextjs 示例中创建的 store.js 文件。将 import storage from 'redux-persist/lib/storage' 替换为 import storage from './storage' 以导入您创建的文件。

【讨论】:

【参考方案2】:

我在这里看不到你的减速机,但我猜你没有处理补水案例。 为了在页面刷新时保持状态,您的减速器应该处理 REHYDRATE 情况。这是我的代码中的一个示例:

const Account = (state= INIT_STATE, action) => 
    switch (action.type) 
    /// other cases here....
    case REHYDRATE:
        const rehydrated = (action && action.payload && action.payload.Account) || 
        return  ...state, ...rehydrated 
    default: return  ...state ;

【讨论】:

以上是关于如何在 Next.js 中持久化 redux 状态数据?的主要内容,如果未能解决你的问题,请参考以下文章

Next js 应用刷新时,useEffect 不调度 redux saga 动作并更新状态

如何更新 LocalStorage 中持久化的 Redux 状态结构

我已经在 next js 中使用 next-redux-wrapper 成功实现了 redux-persist

Next.js+Redux 认证和重定向

如何修复 axios Next js 中的“错误:请求失败,状态码为 404”

redux 如何与 next.js 一起工作?