使用 next-redux-wrapper 时访问 React 外部的 Redux 存储

Posted

技术标签:

【中文标题】使用 next-redux-wrapper 时访问 React 外部的 Redux 存储【英文标题】:Access Redux store outside React when using next-redux-wrapper 【发布时间】:2019-11-10 08:09:31 【问题描述】:

我有一个 NextJS React 应用程序,它在 _app.tsx 上使用 next-react-wrapper(基本上是一个 HOC),如下所示:

_app.tsx

...
import withRedux from 'next-redux-wrapper';

class Page extends App<Props> 
  ...


export default withRedux(reduxStore)(Page);

store.ts

import  applyMiddleware, createStore  from 'redux';
import  composeWithDevTools  from 'redux-devtools-extension/developmentOnly';

import rootReducer from './reducer';

export default (
  initialState: any = undefined,
) => createStore(
  rootReducer,
  initialState,
  composeWithDevTools(applyMiddleware()),
);

我正在努力研究如何在 React 之外访问商店,例如在一个简单的帮助函数中。我的 store.ts 文件导出了一个 makeStore 函数,它是 next-redux-wrapper HOC 所需的(包括初始状态)。

我可以在 React 组件中访问 store,每次都将它作为参数传递给我的辅助函数,但这看起来很混乱。

有没有办法直接从非 React 辅助功能模块访问 store?

【问题讨论】:

【参考方案1】:

您可以创建高阶函数来用 store 包装任何其他函数。这是一个简单的例子,它将 store 作为 this 参数传递给任何其他函数。

function withReduxFunction(store) 
    return function (connectedFunction) 
        return function (...args) 
            connectedFunction.call(store, ...args);
        
    

和用法。例如我们想为这个函数提供商店

function doSomthingWothStore(arg1, arg2) 
    console.log(this);   // This will be store
    console.log("arg1: " + arg1 + " arg2 " + arg2);

const funcWithStore = withReduxFunction(store)(doSomthingWothStore);

现在您可以调用funcWithStorethis 将等于存储。

您可以使用高阶函数以使其适合您(即,将 store 作为第一个参数传递,依此类推)。

您还可以查看useDispatchuseSelector hooks from react-redux。它们也应该适用于任何功能。

【讨论】:

这与从 React 组件访问 store 并手动将其作为参数传递给我的函数不是基本相同吗? 这有点类似于组件与withRedux 连接存储的方式。您连接一次,然后多次调用它而不显式传递商店【参考方案2】:

您可以在任何需要的地方导入 store 模块,并直接访问 store 功能,如store.getState()。但是,您需要订阅 store 才能在状态发生任何变化时收到通知。

【讨论】:

我不确定如何在我的场景中将 store 导入函数。 store 是在一个函数内部通过 next-with-redux HOC 创建的。我没有看到导入商店的简单方法... 你必须从它被实例化的模块中导出存储并在任何地方导入该模块。 在调用它的包装函数之前它没有被初始化,我该如何导出它?这就是 next-with-redux HOC 的工作原理。【参考方案3】:

这可能不是优选的,但可以使用storeKey 从窗口访问商店。默认键是__NEXT_REDUX_STORE__,使用它看起来像这样:

window.__NEXT_REDUX_STORE__.getState()

Here's where that happens

可以在传递给 withRedux 函数参数的第二个选项参数中更改密钥 (storeKey)。对于您的实现,它看起来像这样:

export default (
  initialState: any = undefined,
   storeKey: 'whateveryouwant'  // the name on the exposed store variable
) => createStore(
  rootReducer,
  initialState,
  composeWithDevTools(applyMiddleware()),
);

【讨论】:

有没有办法从服务器端访问它,因为窗口变得未定义 对于静态编译的应用程序(使用next export),是否会在每次刷新时重置商店的状态?如果是这样......如何解决这个问题? @7ball 是的,s-s-r 和 SSG(静态)站点就是这种情况。最流行的解决方案是使用状态持久库(例如 redux-persist)。【参考方案4】:

我遇到了同样的问题,但找到了解决方案。

这个库的自述文件给出了makeStore函数的例子,如下所示:

const makeStore = (initialState, options) => 
    return createStore(reducer, initialState);
;

你需要稍微修改一下

let store;
const makeStore = (initialState, options) => 
    store = createStore(reducer, initialState);
return store;
;

export store

现在您可以从任何您想要的地方导入商店。

【讨论】:

【参考方案5】:

你可以先创建store,然后从makeStore()返回

export const store = createStore(...)
const makeStore() 
  return store

export const wrapper = createWrapper(makeStore,  debug: true )

【讨论】:

以上是关于使用 next-redux-wrapper 时访问 React 外部的 Redux 存储的主要内容,如果未能解决你的问题,请参考以下文章

仅进行“静态生成”时,是不是真的需要在“Next.js + Redux Toolkit”应用程序中使用“next-redux-wrapper”?

next-redux-wrapper 中的空状态

我是不是正确理解了 next-redux-wrapper 的行为?

如何使用 typescript、next-redux-wrapper、getServerSideProps?

将 getStaticProps 与 next-redux-wrapper 一起使用

使用 next-redux-wrapper 将 Google Analytics 添加到 Nextjs 应用程序