{"id":19464370,"url":"https://github.com/react-boilerplate/redux-injectors","last_synced_at":"2025-04-05T14:08:11.295Z","repository":{"id":35136616,"uuid":"203205248","full_name":"react-boilerplate/redux-injectors","owner":"react-boilerplate","description":"Asynchronous injectors for Redux reducers and sagas. As used by react-boilerplate.","archived":false,"fork":false,"pushed_at":"2023-04-04T10:54:21.000Z","size":775,"stargazers_count":129,"open_issues_count":4,"forks_count":31,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-12T23:33:20.660Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/react-boilerplate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-19T16:00:46.000Z","updated_at":"2025-01-12T21:55:41.000Z","dependencies_parsed_at":"2024-06-18T13:39:23.955Z","dependency_job_id":"81156916-0b4e-4eeb-b365-537002b91ab4","html_url":"https://github.com/react-boilerplate/redux-injectors","commit_stats":{"total_commits":24,"total_committers":7,"mean_commits":"3.4285714285714284","dds":0.5416666666666667,"last_synced_commit":"9fae3c171993ff0e25f3b4ba75857dbc6fbf7850"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-boilerplate%2Fredux-injectors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-boilerplate%2Fredux-injectors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-boilerplate%2Fredux-injectors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-boilerplate%2Fredux-injectors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/react-boilerplate","download_url":"https://codeload.github.com/react-boilerplate/redux-injectors/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247345853,"owners_count":20924102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T18:14:43.396Z","updated_at":"2025-04-05T14:08:11.246Z","avatar_url":"https://github.com/react-boilerplate.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg src=\"https://raw.githubusercontent.com/react-boilerplate/redux-injectors/3d1e0d2be038bc710c5f319ca680dd6a1e88d5e8/img/logo.svg?sanitize=true\" alt=\"alt text\" width=\"400\"\u003e\u003c/img\u003e\n\u003cimg src=\"https://travis-ci.org/react-boilerplate/redux-injectors.svg?branch=master\" alt=\"build status\"\u003e\u003c/img\u003e\n\nDynamically load [redux](https://redux.js.org/) reducers and [redux-saga](https://redux-saga.js.org/) sagas as needed, instead of loading them all upfront. This has some nice benefits, such as avoiding having to manage a big global list of reducers and sagas. It also allows more effective use of [code-splitting](https://webpack.js.org/guides/code-splitting/). See [motivation](#Motivation). As used by [react-boilerplate](https://github.com/react-boilerplate/react-boilerplate).\n\n## Getting Started\n```bash\nnpm install redux-injectors # (or yarn add redux-injectors)\n```\n\n### Setting up the redux store\nThe redux store needs to be configured to allow this library to work. The library exports a store enhancer that can be passed to the `createStore` function.\n```js\nimport { createStore } from \"redux\";\nimport { createInjectorsEnhancer } from \"redux-injectors\";\n\nconst store = createStore(\n createReducer(),\n initialState,\n createInjectorsEnhancer({\n   createReducer,\n   runSaga,\n })\n)\n```\n\nNote the `createInjectorsEnhancer` function takes two options. `createReducer` should be a function that when called will return the root reducer. It's passed the injected reducers as an object of key-reducer pairs.\n\n```js\nfunction createReducer(injectedReducers = {}) {\n const rootReducer = combineReducers({\n   ...injectedReducers,\n   // other non-injected reducers can go here...\n });\n\n return rootReducer\n}\n```\n\n`runSaga` should usually be `sagaMiddleware.run`. \n\n```js\n  const runSaga = sagaMiddleware.run;\n```\n\n### Redux DevTools\nIf you're using redux devtools, it's **important to set `shouldHotReload` to false**.  This is because otherwise, redux devtools will re-dispatch previous actions when reducers are injected, causing unexpected behavior.\n\nIf using redux-toolkit:\n```js\n  const store = configureStore({\n    devTools: {\n      shouldHotReload: false\n    }\n  })\n```\n\nIf not using redux-toolkit:\n```js\nimport { composeWithDevTools } from 'redux-devtools-extension';\n\nconst composeEnhancers = composeWithDevTools({\n  shouldHotReload: false\n});\n\nconst store = createStore(reducer, composeEnhancers(\n  ...\n));\n```\n\nUnfortunately this causes a separate issue where the action history is cleared when a reducer is injected, **but it's still strongly recommended to set `shouldHotReload` to false**.  There's an [open issue in the redux-devtools repo about this](https://github.com/reduxjs/redux-devtools/issues/378).\n\n### Injecting your first reducer and saga\nAfter setting up the store, you will be able to start injecting reducers and sagas.\n```js\nimport { compose } from \"redux\";\nimport { injectReducer, injectSaga } from \"redux-injectors\";\n\nclass BooksManager extends React.PureComponent {\n render() {\n   return null;\n }\n}\n\nexport default compose(\n  injectReducer({ key: \"books\", reducer: booksReducer }),\n  injectSaga({ key: \"books\", saga: booksSaga })\n)(BooksManager);\n\n```\n\nOr, using hooks:\n```js\nimport { useInjectReducer, useInjectSaga } from \"redux-injectors\";\n\nexport default function BooksManager() {\n  useInjectReducer({ key: \"books\", reducer: booksReducer });\n  useInjectSaga({ key: \"books\", saga: booksSaga });\n\n  return null;\n}\n```\n\n**Note:** while the above usage should work in most cases, you might find your reducers/sagas aren't being injected in time to receive an action.  This can happen, for example, if you dispatch an action inside a `useLayoutEffect` instead of a `useEffect`.  In that case, `useInjectReducer` and `useInjectSaga` return boolean flags that are `true` once the reducers/sagas have finished injecting.  You can check these before rendering children that depend on these reducers/sagas being injected.\n\n```js\nimport { useInjectReducer, useInjectSaga } from \"redux-injectors\";\n\nexport default function BooksManager(props) {\n  const reducerInjected = useInjectReducer({ key: \"books\", reducer: booksReducer });\n  const sagaInjected = useInjectSaga({ key: \"books\", saga: booksSaga });\n\n  if (!reducerInjected || !sagaInjected) {\n    return null;\n  }\n\n  return (\n    \u003c\u003e\n      {props.children}\n    \u003c/\u003e\n  );\n}\n```\n\n\n## Documentation\nSee the [**API reference**](docs/api.md)  \nOr the [**example**](example)\n\n## Motivation\nThere's a few reasons why you might not want to load all your reducers and sagas upfront:\n1. You don't need all the reducers and sagas for every page. This library lets you only load the reducers/sagas that are needed for the page being viewed. This speeds up the page load time because you can take advantage of [code-splitting](https://webpack.js.org/guides/code-splitting/).  This is also good for performance after the page has loaded, because fewer reducers and sagas are running. \n2. You don't want to have to manage a big list of reducers/sagas. This library lets components inject their own reducers/sagas, so you don't need to worry about adding reducers/sagas to a global list.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-boilerplate%2Fredux-injectors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freact-boilerplate%2Fredux-injectors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-boilerplate%2Fredux-injectors/lists"}