使用 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);
现在您可以调用funcWithStore
和this
将等于存储。
您可以使用高阶函数以使其适合您(即,将 store 作为第一个参数传递,依此类推)。
您还可以查看useDispatch
和useSelector
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 的行为?
如何使用 typescript、next-redux-wrapper、getServerSideProps?