首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从单个组件访问多个易用存储

从单个组件访问多个易用存储
EN

Stack Overflow用户
提问于 2021-02-02 02:21:39
回答 1查看 493关注 0票数 3

我试图在一个组件中访问两个不同的商店,但担心我的应用程序的架构可能需要改变,因为easy-peasy可能没有这个功能。

我有一台GlobalStore

代码语言:javascript
复制
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出现在我的应用程序的顶层。

代码语言:javascript
复制
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,它指示组件中哪个视图是活动的。

代码语言:javascript
复制
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中不存在

代码语言:javascript
复制
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')}>

这个是可能的吗?任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2021-02-27 01:26:47

备选方案1:扩展全局存储

要访问这两个存储区(通过StoreProvider中的useStoreState/Actions ),可以将两个“子”存储区都嵌套到GlobalStore

代码语言:javascript
复制
// SearchModel.js
import { action } from 'easy-peasy';

const searchModel = {
  view: 'filter',
  setView: action((state, payload) => {
    state.view = payload;
  }),
};

export default searchModel;
代码语言:javascript
复制
// MenuModel.js
import { action } from 'easy-peasy';

const menuModel = {
  isOpen: false,
  toggle: action((state, payload) => {
    state.isOpen = !state.isOpen;
  }),
};

export default menuModel;
代码语言:javascript
复制
// 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;

这样,您就可以在方便的时候使用钩子访问这两个商店:

代码语言:javascript
复制
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()创建本地存储区

代码语言:javascript
复制
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可能是阻力最小的路径。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65998089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档