我试图在单个组件中访问 2 个不同的商店,但担心我的应用程序的架构可能需要更改为 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;
仅就本示例而言,我将使用 store 中使用的单个状态和操作来定义导航菜单是否打开。GlobalStore 出现在我的应用程序的顶层
App.js
文件。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
这决定了组件中哪个 View 处于事件状态。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;
我现在遇到的问题是,在一个组件中,我需要能够访问两个商店才能使用 setView
更新 View 。行动在SearchStore
并获得 menuOpen
的值来自 GlobalStore
但不能同时访问。我在组件中的示例是,我有一个样式化的组件,单击该组件时会调用操作
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')}>
这可能吗?任何帮助将非常感激。
最佳答案
方案一:扩展全局商店
要访问两个商店(通过 useStoreState/Actions
中的 StoreProvider
),您可以将两个“子”商店嵌套到 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;
这样,您可以在方便时使用钩子(Hook)访问这两个商店: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 可能是阻力最小的路径。
关于javascript - 从单个组件访问多个简单的商店,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65998089/