我试图在一个组件中访问两个不同的商店,但担心我的应用程序的架构可能需要改变,因为easy-peasy可能没有这个功能。
我有一台GlobalStore
import { createStore } from 'easy-peasy';
const globalModel = {
menuOpen: false,
toggleMenu: action((state, payload) => {
state.menuOpen = payload;
}),
};
const GlobalStore = createStore(globalModel);
export default GlobalStore;就本例而言,我将使用存储中使用的单个状态和操作来定义导航菜单是否打开。
在我的App.js文件中,GlobalStore出现在我的应用程序的顶层。
import React from 'react';
import { StoreProvider } from 'easy-peasy';
import GlobalStore from './store/GlobalStore';
const App = () => {
return (
<StoreProvider store={GlobalStore}>
</StoreProvider>
);
};
export default App;现在,沿着这棵树再往下走,我有另一个存储SearchStore,它指示组件中哪个视图是活动的。
import { createStore } from 'easy-peasy';
import { action } from 'easy-peasy';
const searchModel = {
view: 'filter',
setView: action((state, payload) => {
state.view = payload;
}),
};
const SearchStore = createStore(searchModel);
export default SearchStore;我现在遇到的问题是,在一个组件中,我需要能够访问这两个存储,以使用SearchStore中的setView操作更新视图,并从GlobalStore中获取menuOpen的值,但不能同时访问这两个存储。
我在组件中的示例是,我有一个样式化的组件,当单击它时会调用动作setView,但它的位置也由menuOpen是否为true来定义。但是很明显,如果我尝试获取menuOpen的状态,它将是未定义的,因为它在SearchStore中不存在
const Close = styled.span`
$(({ menuOpen }) => menuOpen ? `
// styles go here
` : `` }
`;
const setView = useStoreActions((action) => action.setView);
const menuOpen = useStoreState((state) => state.menuOpen);
<Close menuOpen={menuOpen} onClick={() => setView('list')}>这个是可能的吗?任何帮助都将不胜感激。
发布于 2021-02-27 01:26:47
备选方案1:扩展全局存储
要访问这两个存储区(通过StoreProvider中的useStoreState/Actions ),可以将两个“子”存储区都嵌套到GlobalStore中
// SearchModel.js
import { action } from 'easy-peasy';
const searchModel = {
view: 'filter',
setView: action((state, payload) => {
state.view = payload;
}),
};
export default searchModel;// MenuModel.js
import { action } from 'easy-peasy';
const menuModel = {
isOpen: false,
toggle: action((state, payload) => {
state.isOpen = !state.isOpen;
}),
};
export default menuModel;// GlobalStore.js
import { createStore } from 'easy-peasy';
import menu from './MenuhModel';
import search from './SearchModel';
const globalModel = {
menu,
search,
};
const GlobalStore = createStore(globalModel);
export default GlobalStore;这样,您就可以在方便的时候使用钩子访问这两个商店:
const searchState = useStoreState((state) => state.search);
const menuState = useStoreState((state) => state.menu);
const searchActions = useStoreActions((action) => action.search);
const menuActions = useStoreActions((action) => action.menu);备选方案2:useLocalStore()
如果不想扩展全局存储区,可以使用useLocalStore()创建本地存储区
function Menu() {
const [state, actions] = useLocalStore(() => ({
isOpen: false,
toggle: action((state, payload) => {
state.isOpen = !state.isOpen;
}),
}));
return (
<div>
{state.isOpen && <MenuItems />}
<button onClick={() => actions.toggle()}>Open menu</button>
</div>
);
}然而,这种方法的缺点是状态不是全局的,并且仅在组件级别可用。
然而,您可以通过创建自己的提供商来绕过这一点-但话又说回来,备选方案1可能是阻力最小的路径。
https://stackoverflow.com/questions/65998089
复制相似问题