Skip to content

Instantly share code, notes, and snippets.

@Tnifey
Created October 27, 2021 20:11
Show Gist options
  • Save Tnifey/9f6c82a3b2ad571c669cb72cac225222 to your computer and use it in GitHub Desktop.
Save Tnifey/9f6c82a3b2ad571c669cb72cac225222 to your computer and use it in GitHub Desktop.
react-pluggable ReduxPlugin MVP

If you have RendererPlugin you can render component and use redux hooks inside etc

import { IPlugin } from "react-pluggable";
export default class ClockPlugin implements IPlugin {
init(pluginStore) {
this.pluginStore = pluginStore;
}
getPluginName() {
return `ClockPlugin@0.0.0`;
}
getDependencies() {
return ['ReduxPlugin@0.0.0'];
}
activate() {
// register reducer
this.pluginStore.executeFunction(
`ReduxPlugin.addReducer`,
"clock",
this.reducer.bind(this)
);
// prepare action
const action = {
type: "SET_DATE",
payload: new Date().toISOString(),
};
// dispatch(action)
this.pluginStore.executeFunction(`ReduxPlugin.dispatch`, action);
}
deactivate() {
this.pluginStore.executeFunction(`ReduxPlugin.removeReducer`, 'clock')
}
// reducer function
reducer(state = { time: null }, action) {
switch (action.type) {
case "SET_DATE":
return {
...state,
time: action.payload,
};
default:
return state;
}
}
}
import {
createPluginStore,
PluginProvider,
RendererPlugin,
} from "react-pluggable";
// create plugin store
const pluginStore = createPluginStore();
export default pluginStore;
// this is redux store
import store from "./store";
// thoose reducers are same as in ./store
import * as defaultReducers from "./reducer";
// install as first plugin
import ReduxPlugin from "./redux-plugin";
pluginStore.install(new ReduxPlugin(store, defaultReducers));
// install other plugins
import ClockPlugin from "./clock-plugin";
pluginStore.install(new ClockPlugin());
export const catReducer = (state, action) => {
switch (action.type) {
case "SET_CAT_NAME":
return {
name: action.payload,
};
default:
return state;
}
};
import { Reducer, Store, combineReducers, AnyAction } from "redux";
import { IPlugin, PluginStore } from "react-pluggable";
export default class ReduxPlugin implements IPlugin {
private name = "ReduxPlugin";
private version = "0.0.0";
pluginStore!: PluginStore;
private _defaultReducers = {};
private _reducers = {};
getPluginName(): string {
return `${this.name}@${this.version}`;
}
getDependencies() {
return [];
}
constructor(public store: Store, defaultReducers = {}) {
this._defaultReducers = { ...defaultReducers };
this._reducers = { ...defaultReducers };
}
init(pluginStore: PluginStore) {
this.pluginStore = pluginStore;
}
functionsMap() {
return {
dispatch: this.store.dispatch,
getState: this.store.getState,
addReducer: this.addReducer,
removeReducer: this.removeReducer,
};
}
activateFunctions() {
Object.entries(this.functionsMap()).forEach(([functionName, callback]) => {
this.pluginStore.addFunction(
`${this.name}.${functionName}`,
callback.bind(this)
);
});
}
deactivateFunctions() {
Object.entries(this.functionsMap()).forEach(([functionName]) => {
this.pluginStore.removeFunction(`${this.name}.${functionName}`);
});
}
activateReducers() {
const reducer = combineReducers(this._reducers);
this.store.replaceReducer(reducer);
}
deactivateReducers() {
const root = combineReducers(this._defaultReducers);
this.store.replaceReducer(root);
}
deactivate() {
const root = combineReducers(this._defaultReducers);
this.store.replaceReducer(root);
this.deactivateFunctions();
}
activate() {
this.activateReducers();
this.activateFunctions();
}
addReducer(name: string, reducer: Reducer) {
this._reducers[name] = reducer;
this.activateReducers();
}
removeReducer(name: string) {
delete this._reducers[name];
this.activateReducers();
}
dispatch(action: AnyAction) {
return this.store.dispatch(action);
}
getState() {
return this.store.getState();
}
}
import * as reducers from "./reducer";
import { configureStore, combineReducers } from "@reduxjs/toolkit";
const store = configureStore({
reducer: combineReducers({ ...reducers }),
});
export default store;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment