javascript - 从单个组件访问多个简单的商店

标签 javascript reactjs easy-peasy

我试图在单个组件中访问 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/

相关文章:

javascript - “Jest 在 react 应用程序上遇到意外的 token {”错误

javascript - navigator.onLine 在 Electron 中总是返回 true

javascript - 如何在动态导入功能中导入Sequelize?

javascript - 如何根据列表 Angular 2/4 中的选项显示 Div 的内容

javascript - 在 ES6 之前的代码中使用 "let"和 "const"可以吗?

node.js - 使用 socket.io 和 webpack 构建 React 应用程序不起作用

javascript - 使用javascript更改类的CSS样式,但不在DOM中

react-redux - Easy Peasy VS React Redux

reactjs - easy-peasy:useStoreState 不适用于 ES6 类实例