{"id":17233867,"url":"https://github.com/caseywebdev/cursors","last_synced_at":"2025-12-12T03:46:48.744Z","repository":{"id":17836484,"uuid":"20745382","full_name":"caseywebdev/cursors","owner":"caseywebdev","description":"Maintain your React state with Cursors.","archived":false,"fork":false,"pushed_at":"2016-04-18T15:19:41.000Z","size":583,"stargazers_count":79,"open_issues_count":0,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-06-12T03:50:57.953Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://ca.sey.me/cursors/test.html","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/caseywebdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-06-11T21:44:26.000Z","updated_at":"2025-06-05T18:39:21.000Z","dependencies_parsed_at":"2022-07-08T06:00:27.501Z","dependency_job_id":null,"html_url":"https://github.com/caseywebdev/cursors","commit_stats":null,"previous_names":["caseywebdev/curator"],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/caseywebdev/cursors","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseywebdev%2Fcursors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseywebdev%2Fcursors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseywebdev%2Fcursors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseywebdev%2Fcursors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/caseywebdev","download_url":"https://codeload.github.com/caseywebdev/cursors/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseywebdev%2Fcursors/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264940397,"owners_count":23686250,"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-10-15T05:27:03.087Z","updated_at":"2025-12-12T03:46:48.703Z","avatar_url":"https://github.com/caseywebdev.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cursors\n\nMaintain your React state with Cursors.\n\nCursors is a [React] mixin that is inspired by [David Nolen]'s [Om]. This is a\nmuch lighter implementation that is focused on Nolen's idea of a single global\nstate and using cursors to create smaller local states within a single shared\ndata structure.\n\nCursors leverages the [Immutability Helpers] provided by [React Add-ons]. By\navoiding mutation, tasks like undo/redo become trivial, reasoning about problems\nbecomes easier, and bugs are easier to avoid.\n\n## Install\n\n```bash\nbower install cursors\n```\n\n## API\n\n### Top-Level\n\n#### Cursors\n\nThe Cursors object itself should be mixed-in to all Cursors-using components.\n\n### Component-Level\n\n#### this.getCursor(key, [path])\n\nReturns a new `cursor` with its path set to `key`'s path concatenated with\n`path`. `key` and `path` should both be a `string` or `number`. Use an array of\n`string`s and/or `number`s for `path` if your path goes more than one level\ndeep.\n\n#### this.update(deltas)\n\nUpdate the state with the change definitions in `deltas`. For `delta` syntax\ncheck out React's [Immutability Helpers].\n\n## Examples\n\nCheck out [the test file](https://caseywebdev.github.io/cursors/test.html) for a\nfull example. Here's the basics:\n\n```js\nvar User = React.createClass({\n\n  // First, mixin Cursors to add the appropriate functions to this component\n  // definition.\n  mixins: [Cursors],\n\n  // In order for state changes to be recognized globally, you should never need\n  // to use `this.setState`. Instead, use `this.update`. `update` takes a key\n  // and a delta object. Check the \"Immutability Helpers\" link for more\n  // information. By using `update`, the value will be updated at the root level\n  // of the cursor, and changes will be propagated down back to the children.\n  // This is a huge win for cursors, because it removes the need to nest\n  // callbacks down for changes to objects that live higher up in the hierarchy.\n  handleChange: function (ev) {\n    this.update({user: {name: {$set: ev.target.value}}});\n  },\n\n  // The value of any cursors passed into this component will be reflected in\n  // the `this.state` object. This interface allows children to not depend on\n  // being passed cursors, but use them transparently if they are passed.\n  render: function () {\n    return \u003cinput value={this.state.user.name} onChange={this.handleChange} /\u003e;\n  }\n});\n\nvar Users = React.createClass({\n\n  // First, mixin Cursors to add the appropriate functions to this component\n  // definition.\n  mixins: [Cursors],\n\n  // The only component that should need to define `getInitialState` is the root\n  // component. Child components can define their initial state, but state that\n  // is passed into them via parent cursors will override the corresponding\n  // initial state.\n  getInitialState: function () {\n    return {\n      users: this.props.users || []\n    };\n  },\n\n  // When rendering child components, always pass the appropriate `cursor` for\n  // the child component via `this.getCursor(key, [path])`.\n  renderUser: function (user, i) {\n    return \u003cUser cursors={{user: this.getCursor('users', i)}} /\u003e;\n  },\n\n  render: function () {\n    return \u003cdiv\u003e{this.state.users.map(this.renderUser)}\u003c/div\u003e;\n  }\n});\n\nReact.renderComponent(\n  \u003cMyUsersComponent users={[{name: 'Casey'}, {name: 'Gunner'}]} /\u003e,\n  document.body\n);\n```\n\n[React]: https://github.com/facebook/react\n[David Nolen]: https://github.com/swannodette\n[Om]: https://github.com/swannodette/om\n[Immutability Helpers]: http://facebook.github.io/react/docs/update.html\n[React Add-ons]: http://facebook.github.io/react/docs/addons.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaseywebdev%2Fcursors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcaseywebdev%2Fcursors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaseywebdev%2Fcursors/lists"}