{"id":13452114,"url":"https://github.com/Niryo/controllerim","last_synced_at":"2025-03-23T19:33:38.347Z","repository":{"id":57206657,"uuid":"111235816","full_name":"Niryo/controllerim","owner":"Niryo","description":"A state management library for React","archived":true,"fork":false,"pushed_at":"2022-04-08T12:50:03.000Z","size":2410,"stargazers_count":214,"open_issues_count":0,"forks_count":6,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-03T14:04:12.662Z","etag":null,"topics":["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/Niryo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-18T20:12:55.000Z","updated_at":"2024-08-05T04:59:32.000Z","dependencies_parsed_at":"2022-09-08T14:22:25.250Z","dependency_job_id":null,"html_url":"https://github.com/Niryo/controllerim","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Niryo%2Fcontrollerim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Niryo%2Fcontrollerim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Niryo%2Fcontrollerim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Niryo%2Fcontrollerim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Niryo","download_url":"https://codeload.github.com/Niryo/controllerim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245159023,"owners_count":20570307,"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":["react","state-management"],"created_at":"2024-07-31T07:01:13.442Z","updated_at":"2025-03-23T19:33:37.928Z","avatar_url":"https://github.com/Niryo.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","List"],"sub_categories":[],"readme":"# Controllerim\n\nA simple, clean and well structured state management library for react\n\n[![npm version](https://img.shields.io/npm/v/controllerim.svg)](https://www.npmjs.com/package/controllerim)\n\n## Installation\n\n`npm install controllerim --save`\n\n## Migrating from Controllerim v2 to v3\nThe migration process should be very easy. Follow the docs and the example project for understanding the new API.\n\n## Basic usage example\n\n\n\nInside `ParentController.js`:\n\n```javascript\nimport { controller } from 'controllerim';\n\nclass _ParentController {\n  constructor() {\n    this.state = {\n      message: 'hello' \n    };\n  }\n  getMessage() {\n    return this.state.message;\n  }\n  setMessage(value) {\n    this.state.message = value;\n  }\n}\n\nexport const ParentController = controller(_ParentController);\n```\n\nInside `Parent.jsx`:\n\n```javascript\nimport React, { Component } from 'react';\nimport { observer } from 'controllerim';\nimport { ParentController } from './ParentController';\n\nclass Parent extends Component {\n  constructor(props) {\n    super(props);\n    this.controller = ComponentController.create(); //returns a fresh controller instance\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003ch1\u003e{this.controller.getMessage()}\u003c/h1\u003e\n        \u003cChild/\u003e\n        \u003cbutton onClick={() =\u003e this.controller.setMessage('hello world!')}\u003eClick me to change message\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n};\n\nexport default observer(Parent);\n```\n\nInside `Child.jsx`:\n\n```javascript\nimport React, { Component } from 'react';\nimport { observer} from 'controllerim';\nimport {ParentController} from './ParentController'\n\nclass Child extends Component {\n  constructor(props){\n    super(props);\n    this.parentController = ParentController.getInstance(); //returns an existing instance of the parentController. You could supply an id if you you have more than one instances of the parent controller.\n  }\n \n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cspan\u003eThis is a message from parent: {this.parentController.getMessage()}\u003c/span\u003e\n      \u003c/div\u003e\n    );\n  }\n};\n\nexport default observer(Child);\n```\n### Example project\n\nHere is a [Simple example project](https://niryo.github.io/controllerim/)\nYou can see the source code under the example folder: [demo-app/src](demo-app/src)\nIf you want to run it locally:\nAfter cloning the repository, navigate to the demo-app folder and type in your terminal:\n\n```\nnpm install\nnpm start\n```\n\n## How\n\nControllerim utilizes [Mobx](https://github.com/mobxjs/mobx) behind the scenes. You don't need to learn Mobx in order to use Controllerim, but a basic understanding of Mobx is recommended.\n\n## Api\n\n### `controller(controllerClass)`\n##### Arguments:\n* **controllerClass**: any es6 class with a state member.\n##### Returns:\n* **Object: { create(), getInstance() }**: an object with two factory methods for getting a new controller instance \n\nA controller is a plain Javascript class that holds a  **state** and methods for manipulating the state.\nAll the methods of the controller are smartly memoized and computed, thus if you do some heavy calculation, it will be re-calculated when really needed.\n\nThe observers (React Components that you wrapped within `observer`) will react to any change in the state, even changes of deep nested properties.\n\n#### `create(id?: string (default: 'globalInstance') )`:\n\nReturns a new instance of the given controller. You should use this method when you know for sure that you need a fresh instance and not an existing one (most of the time you should prefer `create` over `getInstance`). You can pass an `id`, for being used later by getInstance.\n\n#### `getInstance(id?: string (default: 'globalInstance'))`:\nReturns an existing instance of the given controller, or a new one if there isn't any existing instance yet. If you don't supply an `id`, the return value will be the default global instance.\n\n\n#### controller Usage example:\n\n```javascript\nimport {controller} from 'controllerim';\n\nclass _AppController {\n  constructor() {\n    this.state = {totalNotesCount: 2};                                 \n  }\n\n  getTotalNotesCount() {\n    return this.state.totalNotesCount;\n  }\n\n  increaseCounter() {\n    this.state.totalNotesCount++;\n  }\n}\n\nexport const AppController = controller(_AppController);\n```\n\nYour React component will create an instance of the controller like this: \n\n```javascript\nimport {AppController} from 'controllerim';\n\nclass App extends React.Component {\n  constructor(props) {\n    super(props);\n    this.controller = AppController.create();\n  }\n\n  render(){\n    \u003cdiv\u003e\n      \u003cdiv\u003e{this.controller.getTotalNotesCount()}\u003c/div\u003e\n      \u003cdiv onPress={() =\u003e this.controller.increaseCounter()}\u003eclick me\u003c/div\u003e\n    \u003c/div\u003e\n  }\n}\n```\n\n### `useController(controllerInstance)`\n\nAllows you to use controller inside a functional component. Note that you still have to wrap your functional component within `observer`.\n\n```javascript\nimport React from 'react';\nimport {observer, useController} from 'controllerim';\nimport {FunctionalComponentController} from './TestComponentController';\n\nexport const FunctionalComponent = observer(() =\u003e {\n  const controller = useController(FunctionalComponentController.create());\n  return (\n    \u003cdiv\u003e\n      \u003cdiv\u003e{controller.getUserName()}\u003c/div\u003e\n      \u003cdiv onClick={() =\u003e controller.changeUserName()}\u003eclick me\u003c/div\u003e\n    \u003c/div\u003e\n  );\n});\n```\n### `observer(ReactComponent)`\n\nTo become reactive, every React component that uses a controller, should be wrapped within `observer`. \n\n```javascript\nimport {observer} from 'controllerim';\n\nexport const SomeSmartComponent = observer(class extends React.Component {\n...\n})\n```\n\n### `store(storeClass)`\nA store is just a global singleton controller that is not conceptually bound to any specific component. \n\ninside `AppStore.js`:\n```javascript\n  import {store} from 'controllerim';\n\n  class _AppStore {\n    constructor(){\n      this.state = {useName: 'bla'};\n    }\n\n    getUserName() {\n      return this.state.userName;\n    }\n  }\n\n  export const AppStore = store(_AppStore);\n```\n\nInside `component.jsx`:\n\n```javascript\nimport React from 'react';\nimport {observer} from 'controllerim'\nimport {AppStore} from './AppStore';\n\nclass SomeComponent extends React.Component {\n  render(){\n    \u003cdiv\u003e{AppStore.getUserName()}\u003c/div\u003e // \u003c== The component will re-render on any change in getUserName\n  }\n}\n\nexport default observer(SomeComponent);\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNiryo%2Fcontrollerim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNiryo%2Fcontrollerim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNiryo%2Fcontrollerim/lists"}