Last active
April 14, 2022 20:22
-
-
Save dthtien/d9ba9faabc73ce62069793b622243b6f to your computer and use it in GitHub Desktop.
React Redux code splitting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//uttils/createStore.js | |
import { combineReducers, applyMiddleware, createStore, compose } from "redux"; | |
import reducerRegistry from "./reducerRegistry"; | |
import createSagaMiddleware from "redux-saga"; | |
export const sagaMiddleware = createSagaMiddleware(); | |
const initialState = {}; | |
const enhancers = []; | |
const middleware = [sagaMiddleware]; | |
if (process.env.NODE_ENV === "development") { | |
// eslint-disable-next-line no-underscore-dangle | |
const devToolsExtension = window.__REDUX_DEVTOOLS_EXTENSION__; | |
if (typeof devToolsExtension === "function") { | |
enhancers.push(devToolsExtension()); | |
} | |
} | |
const composedEnhancers = compose( | |
applyMiddleware(...middleware), | |
...enhancers | |
); | |
const reducer = combineReducers(reducerRegistry.reducers); | |
const store = createStore(reducer, initialState, composedEnhancers); | |
const combine = reducers => { | |
const reducerNames = Object.keys(reducers); | |
Object.keys(initialState).forEach(item => { | |
if (reducerNames.indexOf(item) === -1) { | |
reducers[item] = (state = null) => state; | |
} | |
}); | |
return combineReducers(reducers); | |
}; | |
reducerRegistry.emitChange = reducers => | |
store.replaceReducer(combine(reducers)); | |
export default store; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//index.js | |
import React from "react"; | |
import ReactDOM from "react-dom"; | |
import { createBrowserHistory } from "history"; | |
import { Provider } from "react-redux"; | |
import store from "./utils/createStore"; | |
// core components | |
import SomeComponent from "layouts/SomeComponent.js"; | |
const hist = createBrowserHistory(); | |
ReactDOM.render( | |
<Provider store={store}> | |
<SomeComponent/> | |
</Provider>, | |
document.getElementById("root") | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//utils/reducerInjector.js | |
import React from "react"; | |
import { ReactReduxContext } from "react-redux"; | |
import reducerRegistry from "./reducerRegistry"; | |
import { sagaMiddleware } from "./createStore"; | |
export default ({ key, reducer, saga }) => WrappedComponent => { | |
class ReducerInjector extends React.Component { | |
static WrappedComponent = WrappedComponent; | |
static contextType = ReactReduxContext; | |
static displayName = `withReducer(${WrappedComponent.displayName || | |
WrappedComponent.name || | |
"Component"})`; | |
constructor(props, context) { | |
super(props, context); | |
reducerRegistry.register(key, reducer); | |
if (saga) { | |
sagaMiddleware.run(saga); | |
} | |
} | |
render() { | |
return <WrappedComponent {...this.props} />; | |
} | |
} | |
return ReducerInjector; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//utils/reducerRegistry.js | |
export class ReducerRegistry { | |
constructor() { | |
this._emitChange = null; | |
this._reducers = {}; | |
} | |
get reducers() { | |
return { ...this._reducers }; | |
} | |
set emitChange(listener) { | |
this._emitChange = listener; | |
} | |
register(name, reducer) { | |
this._reducers = { ...this._reducers, [name]: reducer }; | |
if (this._emitChange) { | |
this._emitChange(this.reducers); | |
} | |
} | |
} | |
const reducerRegistry = new ReducerRegistry(); | |
export default reducerRegistry; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//views/SomeComponent/index.js | |
import React from "react"; | |
import { connect } from "react-redux"; | |
import { compose } from "redux"; | |
import reducer, { reducerName as key } from "./reducer"; | |
// import reducerRegistry from "utils/reducerRegistry"; | |
import reducerInjector from "utils/reducerInjector"; | |
function SomeComponent() { | |
const classes = useStyles(); | |
return <h1>The awesome component!</h1> | |
} | |
const withConnect = connect( | |
null, | |
null | |
); | |
const withReducer = reducerInjector({ key, reducer }); | |
export default compose( | |
withConnect, | |
withReducer | |
)(SomeComponent); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment