【问题标题】:Connecting Redux Stores using Redux Toolkit使用 Redux Toolkit 连接 Redux Store
【发布时间】:2021-09-21 08:09:55
【问题描述】:

由于各种原因,我的工作场所目前正在尝试将 React/Redux 引入我们的项目中。我们的项目使用 Shopify 和它的 Liquid 模板以及 jQuery。他们想要迁移到 React,到目前为止,我们一直在通过查找特定 ID 并以这种方式注入 React 组件来注入 React。

由于这个原因,并且因为我们现在需要一个存储来保存和呈现数据,所以我遇到了一个奇怪的问题。如果我用 Provider 和 store 包装这些注入组件中的每一个,我基本上可以让每个组件都有自己的 store,但这根本没有帮助,因为它几乎是在模仿本地状态。

有没有办法让我“连接”并与多个组件共享商店?

我曾考虑像通常情况那样包装整个项目,但这样做会/应该使 Liquid 无用。

下面是一个例子:

import ReactDOM from "react-dom";
import React from "react";

import attrToProps from "../../../partials/data-attribute-to-props.js";
import FavoritesToggler from "./index.js";
import store from "./../../Store/store"
import { Provider } from "react-redux"

const rootEl = document.getElementById("fav-container-react");

if(rootEl) {
    const props = attrToProps(rootEl.attributes);
    rootEl && ReactDOM.render(<Provider store={store}><FavoritesToggler {...props} /></Provider>, rootEl);
}

这被注入到一个包含 'fav-container-react' id 的 div 中。

但我们目前有几个这样的,我想知道如何让它们连接到同一个商店。

任何想法都将不胜感激,包括可能的架构变化(我们需要“显示进度”才能继续获得资金,因此不能选择启动新项目。这意味着我需要一个解决方案能够不断将遗留代码更新为 React)

【问题讨论】:

    标签: javascript reactjs redux store redux-toolkit


    【解决方案1】:

    如果组件具有 store 属性并且您使用 connect,则不需要提供程序。 hooks 不起作用,所以我建议使用可以在所有项目都转换为 React 时使用钩子重构的容器。

    const { connect } = ReactRedux;
    const { createStore, applyMiddleware, compose } = Redux;
    
    const initialState = { counter: 0 };
    //action types
    const UP = 'UP';
    //action creators
    const up = () => ({
      type: UP,
    });
    const reducer = (state, { type }) => {
      if (type === UP) {
        return { ...state, counter: state.counter + 1 };
      }
      return state;
    };
    //selectors
    const selectCounter = (state) => state.counter;
    //creating store with redux dev tools
    const composeEnhancers =
      window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const store = createStore(
      reducer,
      initialState,
      composeEnhancers(
        applyMiddleware(
          () => (next) => (action) => next(action)
        )
      )
    );
    const App = ({ count, up }) => {
      return <button onClick={up}>{count}</button>;
    };
    const AppContainer = connect(
      (state) => ({
        count: selectCounter(state),
      }),
      { up }
    )(App);
    
    const OtherContainer = connect(
      (state) => ({
        count: selectCounter(state),
      })
    )(({count})=><h1>{count}</h1>);
    
    ReactDOM.render(
      <AppContainer store={store} />,
      document.getElementById('root-1')
    );
    ReactDOM.render(
      <AppContainer store={store} />,
      document.getElementById('root-2')
    );
    ReactDOM.render(
      <OtherContainer store={store} />,
      document.getElementById('root-3')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
    
    <div id="root-1"></div>
    <div id="root-2"></div>
    <div id="root-3"></div>

    【讨论】:

    • 我刚试过这个。不幸的是,这似乎与我使用 Provider 包装时的结果相同。我尝试将此按钮放在产品卡中,并且在循环时它在所有产品卡中都可以使用(与以前的 Provider 方法相同),但是当我将它放在另一个组件中,并用连接包装一个 AppContainer 并将组件注入它,它不起作用。我认为它很可能在这里工作,因为他们使用的是完全相同的 AppContainer。
    • @asegier 你的断言是错误的。我更改了 sn-p 以使用另一个容器和组件并创建了一个 sandbox 如果它不适合您,您能否提供一个沙箱来演示什么不起作用?
    猜你喜欢
    • 2021-04-15
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 2020-04-24
    • 2018-08-25
    • 2022-07-16
    • 2021-08-02
    • 1970-01-01
    相关资源
    最近更新 更多