{"id":15373962,"url":"https://github.com/sebastiandedeyne/react-incision","last_synced_at":"2026-05-04T02:35:53.602Z","repository":{"id":146393799,"uuid":"149508835","full_name":"sebastiandedeyne/react-incision","owner":"sebastiandedeyne","description":"A subtree state management library when setState just doesn't cut it","archived":false,"fork":false,"pushed_at":"2018-09-20T20:49:07.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-31T21:43:27.989Z","etag":null,"topics":["contextapi","react","state-management"],"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/sebastiandedeyne.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"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":"2018-09-19T20:32:25.000Z","updated_at":"2018-09-20T20:49:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"14f15060-2b8d-4ce4-8d03-0803707e8cf4","html_url":"https://github.com/sebastiandedeyne/react-incision","commit_stats":{"total_commits":8,"total_committers":1,"mean_commits":8.0,"dds":0.0,"last_synced_commit":"566ef7de051c3045e0e56735e3f42f098e44cc3c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sebastiandedeyne/react-incision","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastiandedeyne%2Freact-incision","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastiandedeyne%2Freact-incision/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastiandedeyne%2Freact-incision/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastiandedeyne%2Freact-incision/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sebastiandedeyne","download_url":"https://codeload.github.com/sebastiandedeyne/react-incision/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastiandedeyne%2Freact-incision/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32592715,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T22:12:39.696Z","status":"online","status_checked_at":"2026-05-04T02:00:06.625Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["contextapi","react","state-management"],"created_at":"2024-10-01T13:56:52.215Z","updated_at":"2026-05-04T02:35:53.568Z","avatar_url":"https://github.com/sebastiandedeyne.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# A subtree state management library when setState just doesn't cut it\n\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)\n[![Latest Version on NPM](https://img.shields.io/npm/v/react-incision.svg?style=flat-square)](https://npmjs.com/package/react-incision)\n\nReact Incision is a small state management library built on [React 16's context API](https://reactjs.org/docs/context.html). It allows you to expose a state object, and retrieve or update it further down the component tree.\n\nRetrieve parent state via dot notation, or \"slice\" the parent state in a child component to expose a new, smaller state object. This probably sounds quite abstract, time for a few examples!\n\nFirst, we'll create a stateful component. The goal is to share state with it's child components.\n\n```js\nimport React from \"react\";\nimport Incision from \"react-incision\";\n\nclass Profile extends React.Component {\n  state = {\n    user: {\n      name: \"Sebastian\",\n      address: {\n        streetAddress: \"Samberstraat 69D\",\n        city: \"Antwerp\",\n        zip: \"2060\"\n      }\n    }\n  };\n}\n```\n\nNext, we'll render an `Incision` component, pass our component state, and register an `onChange` handler so Incision can modify our state.\n\n```js\nclass Profile extends React.Component {\n  state = {\n    user: {\n      name: \"Sebastian\",\n      address: {\n        streetAddress: \"Samberstraat 69D\",\n        city: \"Antwerp\",\n        zip: \"2060\"\n      }\n    }\n  };\n\n  render() {\n    return (\n      \u003cIncision\n        state={this.state}\n        onChange={newState =\u003e this.setState(newState)}\n      \u003e\n        \u003cUserForm /\u003e\n      \u003c/Incision\u003e\n    );\n  }\n}\n```\n\nIn the `UserForm` component we rendered above, we can \"operate\" on the parent state by specifying a path. The `Incision.Operate` component accepts a function as it's child. The function is invoked with two arguments: the value and a setter. We can use these to map the `name` property to an input.\n\n```js\nclass UserForm extends React.Component {\n  render() {\n    return (\n      \u003cform\u003e\n        \u003cIncision.Operate path=\"name\"\u003e\n          {(name, setName) =\u003e (\n            \u003clabel\u003e\n              Name:{\" \"}\n              \u003cinput value={name} onChange={e =\u003e setName(e.target.value)} /\u003e\n            \u003c/label\u003e\n          )}\n        \u003c/Incision.Operate\u003e\n      \u003c/form\u003e\n    );\n  }\n}\n```\n\nWhen the user types in the `name` input, the `Profile` component's state will be updated. All state changes are immutable, powered by the amazing [Immer](https://github.com/mweststrate/immer) library.\n\nWe could also operate on a street address using dot notation:\n\n```js\n\u003cIncision.Operate path=\"address.streetAddress\"\u003e\n  {(streetAddress, setStreetAddress) =\u003e (\n    \u003clabel\u003e\n      Street:{\" \"}\n      \u003cinput\n        value={streetAddress}\n        onChange={e =\u003e setStreetAddress(e.target.value)}\n      /\u003e\n    \u003c/label\u003e\n  )}\n\u003c/Incision.Operate\u003e\n```\n\nBesides operating on state values, we can also \"slice\" te state to expose a subset of the state object to child components.\n\n```js\nclass UserForm extends React.Component {\n  render() {\n    return (\n      \u003cform\u003e\n        \u003cIncision.Slice path=\"address\"\u003e\n          \u003cIncision.Operate path=\"streetAddress\"\u003e\n            {(name, setName) =\u003e (\n              \u003clabel\u003e\n                Street:{\" \"}\n                \u003cinput\n                  value={streetAddress}\n                  onChange={e =\u003e setStreetAddress(e.target.value)}\n                /\u003e\n              \u003c/label\u003e\n            )}\n          \u003c/Incision.Operate\u003e\n        \u003c/Incision.Slice\u003e\n      \u003c/form\u003e\n    );\n  }\n}\n```\n\n## Who's this for?\n\nIncise isn't meant to be the main state management library in your application, but is great to augment existing solutions in select parts of your app.\n\nOther libraries (like [Redux](https://github.com/reduxjs/redux), [MobX](https://github.com/mobxjs/mobx), or [Unstated](https://github.com/jamiebuilds/unstated)) are better solutions to deal with your main application logic, because they encapsulate behavior in \"actions\" or similar concepts. Incise is great to reduce boilerplate in places where you don't want or need actions for every single state change, but just want to modify an object.\n\nForms are a perfect use case. An example flow would be:\n\n- Retrieve user data from a redux store\n- Modify the user data with a form containing inputs wrapped in `Incision.Operate` components\n- When the form is submitted, dispatch an action containing the modified `user` object\n\nNo more need for `SET_NAME`, `SET_EMAIL`, etc. actions. The only one we cared about was `UPDATE_PROFILE` anyway. Of course, for simple forms `setState` is probably good enough! Incise was created for those situations where `setState` just doens't cut it.\n\n## Installation\n\nYou can install the package via npm or yarn:\n\n```bash\nnpm install react-incision\n```\n\n```bash\nyarn add react-incision\n```\n\nMake sure `react@^16.5.2` is also installed.\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Testing\n\n```bash\n$ yarn test\n```\n\n## Credits\n\n- [Sebastian De Deyne](https://github.com/sebastiandedeyne)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsebastiandedeyne%2Freact-incision","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsebastiandedeyne%2Freact-incision","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsebastiandedeyne%2Freact-incision/lists"}