{"id":16921372,"url":"https://github.com/blgm/redux-bind-selectors","last_synced_at":"2025-03-22T11:30:55.703Z","repository":{"id":24245237,"uuid":"100993508","full_name":"blgm/redux-bind-selectors","owner":"blgm","description":"A Redux store enhancer for computing derived state by binding selectors to the store","archived":false,"fork":false,"pushed_at":"2024-04-30T09:19:38.000Z","size":2152,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-04-30T10:51:37.309Z","etag":null,"topics":["redux","reselect"],"latest_commit_sha":null,"homepage":"","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/blgm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","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":"2017-08-21T21:19:40.000Z","updated_at":"2024-05-27T12:19:21.845Z","dependencies_parsed_at":"2024-04-30T10:43:28.573Z","dependency_job_id":"1f03fa4e-41e3-4944-a90a-1a3da8afdb4a","html_url":"https://github.com/blgm/redux-bind-selectors","commit_stats":{"total_commits":565,"total_committers":10,"mean_commits":56.5,"dds":"0.43185840707964607","last_synced_commit":"5b63458011cdffaf598ba90f7aeed8fecc558941"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blgm%2Fredux-bind-selectors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blgm%2Fredux-bind-selectors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blgm%2Fredux-bind-selectors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blgm%2Fredux-bind-selectors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blgm","download_url":"https://codeload.github.com/blgm/redux-bind-selectors/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244207715,"owners_count":20416104,"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":["redux","reselect"],"created_at":"2024-10-13T19:51:32.094Z","updated_at":"2025-03-22T11:30:55.320Z","avatar_url":"https://github.com/blgm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm](https://img.shields.io/npm/v/redux-bind-selectors.svg)](https://www.npmjs.com/package/redux-bind-selectors)\n[![test](https://github.com/blgm/redux-bind-selectors/workflows/test/badge.svg?branch=main)](https://github.com/blgm/redux-bind-selectors/actions?query=workflow%3Atest+branch%3Amain)\n\n# redux-bind-selectors\n\nA Redux [store enhancer](https://redux.js.org/glossary#store-enhancer) for computing derived state by binding selectors to a [Redux](http://redux.js.org/) store, so that `getState()` incorporates derived data.\n\n```javascript\nimport { createStore } from 'redux'\nimport bindSelectors from 'redux-bind-selectors'\n\nconst store = createStore(\n  myReducer, // The Redux reducer\n  { numbers: [4, 6, 9, 2] }, // Initial state (optional)\n  bindSelectors({ total }) // Bind the `total` selector\n)\n\nstore.getState()\n// {\n//   numbers: [4, 6, 9, 2], // \u003c-- initial state from the store\n//   total: 21              // \u003c-- result of the `total` selector\n// }\n```\n\n## Installation\n```\nnpm install --save redux-bind-selectors\n```\n\n## Usage\n`bindSelectors()` takes an object where the keys are paths in the state object, and the properties are selector functions.  This is analogous to the Redux `combineSelectors()` function.\n```javascript\nconst enhancer = bindSelectors({\n  selector1: myReselectSelector,\n  selector2: state =\u003e state.a + state.b\n})\n```\nSelectors are pure functions that take the state object as their only argument.  Check out [reselect](https://www.npmjs.com/package/reselect) to build efficient selectors.\n\nWhen creating the store, the enhancer should be the last argument to the `createStore()` function.  If you have more than one enhancer, you can use the `compose()` function in Redux to compose them.\n```javascript\nconst store1 = createStore(reducer, enhancer)\nconst store2 = createStore(reducer, initialState, enhancer)\n```\n\n## Motivation\nA Redux store should contain the *minimum representation* of state, so rather than storing:\n```javascript\n{\n  numbers: [4, 6, 9, 2],\n  total: 21 // \u003c-- this can be calculated from `numbers`\n}\n```\nit should just store:\n```javascript\n{\n  numbers: [4, 6, 9, 2]\n}\n```\nand calculate `total` when needed with a selector:\n```javascript\nconst total = state =\u003e state.numbers.reduce((sum, value) =\u003e sum + value, 0)\n```\n(Pro tip:  [reselect](https://www.npmjs.com/package/reselect) would be more efficient)\n\n#### But...\nInstead of a single, simple state object, **state is now split between the store and a collection of selector functions**, which adds complexity.\n\n#### Solution without `redux-bind-selectors`\nUse `mapStateToProps()` in [React Redux](https://www.npmjs.com/package/react-redux), to [connect the selectors to the state](https://redux.js.org/recipes/computing-derived-data).\n\n#### Solution with `redux-bind-selectors`\nUse this module to bind the selectors to the store, so that the store runs the selectors for you, producing a single object.  This approach retains the advantages of minimum state representation, and separation of concerns between reducers and selectors.\n\n#### Which one should I use?\nIf you are new to React and Redux, then you should initially consider `mapStateToProps()`, as recommended by the [Redux documentation](https://redux.js.org/recipes/computing-derived-data).\n\nYou should try out this module if you are not using React, you prefer to keep view and model logic separate, you live on the edge, or you consider this approach to be more elegant.  It's relatively easy to switch between the two, or do both at the same time.\n\nIf the output of `getState()` is used for other purposes (for instance, to persist the state), then careful consideration should be given as to how this module will affect that.\n\n## Notes\n- A selector cannot have the same path in the state object as a reducer. (This is why we do not simply reuse the `createStructuredSelector()` function from reselect)\n- Paths are all top level object keys\n- A selector cannot return `undefined`, in order to be consistent with Redux where a combined reducer cannot return `undefined`.  Instead, use `null`.\n\n## License\nSee [LICENSE.md](LICENSE.md)\n\n## Contributing\nSee [CONTRIBUTING.md](CONTRIBUTING.md)\n\n[![JavaScript Style Guide](https://cdn.rawgit.com/standard/standard/master/badge.svg)](https://github.com/standard/standard)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblgm%2Fredux-bind-selectors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblgm%2Fredux-bind-selectors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblgm%2Fredux-bind-selectors/lists"}