最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Redux State Sharing in Microfrontend Architecture | 1 host, 1 remote example - Stack Overflow

programmeradmin4浏览0评论

I have currently a host - container and a remote - dashboard.

I have a full blown redux+saga setup at my container, which I am exposing to remote using Module federation as well.

plugins: [
    new ModuleFederationPlugin({
        name: "container",
        filename: "remoteEntry.js",
        remotes: {
            dashboard: "dashboard@http://localhost:8081/remoteEntry.js",
        },
        exposes: {
            './GlobalStore': './src/redux/index.js'
        },
        shared: {
            ...dependencies,
            ...Object.fromEntries(
                singletonDependencies.map(dep => [
                    dep,
                    {
                        singleton: true,
                        requiredVersion: dependencies[dep],
                    }
                ])
            )
        },
    })
]

Now my requirement is to have the dashboard manage it's own particular states, inside the dashboard, I am checking whether the app is running inside the container or not. If it is running standalone I am doing this full-blown redux+saga setup inside there as well (as if it's running individually without knowing there's a container app).

If it's running inside the container, I am using this

import React from 'react';
import { Provider } from "react-redux";
import GlobalStore from 'container/GlobalStore';
import { RouterProvider } from 'react-router';

const InsideContainerApp = ({ router }) => {
    return (
        <Provider store={GlobalStore}>
            <RouterProvider router={router} />
        </Provider>
    );
}

export default InsideContainerApp;

The imported store from the container.

Anyone knows how can I inject my reducers and sagas from the remote to the host in run-time or is it even required to do this way? My ask is that I don't want to define all the slices / reducers in the container and I want my remotes to have full autonomy how they want to define their state structures.

I have currently a host - container and a remote - dashboard.

I have a full blown redux+saga setup at my container, which I am exposing to remote using Module federation as well.

plugins: [
    new ModuleFederationPlugin({
        name: "container",
        filename: "remoteEntry.js",
        remotes: {
            dashboard: "dashboard@http://localhost:8081/remoteEntry.js",
        },
        exposes: {
            './GlobalStore': './src/redux/index.js'
        },
        shared: {
            ...dependencies,
            ...Object.fromEntries(
                singletonDependencies.map(dep => [
                    dep,
                    {
                        singleton: true,
                        requiredVersion: dependencies[dep],
                    }
                ])
            )
        },
    })
]

Now my requirement is to have the dashboard manage it's own particular states, inside the dashboard, I am checking whether the app is running inside the container or not. If it is running standalone I am doing this full-blown redux+saga setup inside there as well (as if it's running individually without knowing there's a container app).

If it's running inside the container, I am using this

import React from 'react';
import { Provider } from "react-redux";
import GlobalStore from 'container/GlobalStore';
import { RouterProvider } from 'react-router';

const InsideContainerApp = ({ router }) => {
    return (
        <Provider store={GlobalStore}>
            <RouterProvider router={router} />
        </Provider>
    );
}

export default InsideContainerApp;

The imported store from the container.

Anyone knows how can I inject my reducers and sagas from the remote to the host in run-time or is it even required to do this way? My ask is that I don't want to define all the slices / reducers in the container and I want my remotes to have full autonomy how they want to define their state structures.

Share Improve this question asked Mar 22 at 13:27 Devansh NigamDevansh Nigam 5571 gold badge6 silver badges8 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I had a project with very similar requirements. Generally speaking You don't need to define all slices/reducers upfront in the container. You can use dynamic reducer injection and saga middleware injection (You can search plenty of resources about it)

I would configure the store to support dynamic reducers and saga injections and expose the helper functions, that way the remote can call those helpers when they mount.

Heres a relevant snippet

    // Dynamic reducer injection
export const injectReducer = (key, reducer) => {   if (!store.asyncReducers[key]) {
        store.asyncReducers[key] = reducer;
        store.replaceReducer({
          ...staticReducers,
          ...store.asyncReducers,
        });   } };
    
    // Dynamic saga injection 
export const injectSaga = (key, saga) => {   if (!store.runningSagas.has(key)) {
        sagaMiddleware.run(saga);
        store.runningSagas.add(key);   } };

after you expose then they can be used like this :

useEffect(() => {
  injectReducer('dashboard', myReducer);
  injectSaga('dashboard', mySaga);
}, []);

Haven't tried it, But it believe you can just create a component such as

const StoreInjector = ({ reducer, saga, reducerKey }) => {
  useEffect(() => {
    injectReducer(reducerKey, reducer);
    injectSaga(reducerKey, saga);
  }, []);
  return null;
};

and just call it in the top of your remote.

发布评论

评论列表(0)

  1. 暂无评论