【问题标题】:Access Redux store outside React when using next-redux-wrapper使用 next-redux-wrapper 时访问 React 外部的 Redux 存储
【发布时间】: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?

【问题讨论】:

    标签: javascript reactjs redux next.js next-redux-wrapper


    【解决方案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 是的,SSR 和 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 })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-25
        • 2021-11-06
        • 1970-01-01
        • 1970-01-01
        • 2021-01-16
        • 2019-11-04
        • 1970-01-01
        • 2018-06-04
        相关资源
        最近更新 更多