Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Niryo/controllerim
A state management library for React
https://github.com/Niryo/controllerim
react state-management
Last synced: 15 days ago
JSON representation
A state management library for React
- Host: GitHub
- URL: https://github.com/Niryo/controllerim
- Owner: Niryo
- License: mit
- Archived: true
- Created: 2017-11-18T20:12:55.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2022-04-08T12:50:03.000Z (over 2 years ago)
- Last Synced: 2024-09-22T04:38:52.915Z (about 2 months ago)
- Topics: react, state-management
- Language: JavaScript
- Homepage:
- Size: 2.3 MB
- Stars: 214
- Watchers: 7
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome - controllerim - A state management library for React (JavaScript)
- awesome-react-state-management - controllerim - A state management library for React (List)
README
# Controllerim
A simple, clean and well structured state management library for react
[![npm version](https://img.shields.io/npm/v/controllerim.svg)](https://www.npmjs.com/package/controllerim)
## Installation
`npm install controllerim --save`
## Migrating from Controllerim v2 to v3
The migration process should be very easy. Follow the docs and the example project for understanding the new API.## Basic usage example
Inside `ParentController.js`:
```javascript
import { controller } from 'controllerim';class _ParentController {
constructor() {
this.state = {
message: 'hello'
};
}
getMessage() {
return this.state.message;
}
setMessage(value) {
this.state.message = value;
}
}export const ParentController = controller(_ParentController);
```Inside `Parent.jsx`:
```javascript
import React, { Component } from 'react';
import { observer } from 'controllerim';
import { ParentController } from './ParentController';class Parent extends Component {
constructor(props) {
super(props);
this.controller = ComponentController.create(); //returns a fresh controller instance
}render() {
return (
{this.controller.getMessage()}
this.controller.setMessage('hello world!')}>Click me to change message
);
}
};export default observer(Parent);
```Inside `Child.jsx`:
```javascript
import React, { Component } from 'react';
import { observer} from 'controllerim';
import {ParentController} from './ParentController'class Child extends Component {
constructor(props){
super(props);
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.
}
render() {
return (
This is a message from parent: {this.parentController.getMessage()}
);
}
};export default observer(Child);
```
### Example projectHere is a [Simple example project](https://niryo.github.io/controllerim/)
You can see the source code under the example folder: [demo-app/src](demo-app/src)
If you want to run it locally:
After cloning the repository, navigate to the demo-app folder and type in your terminal:```
npm install
npm start
```## How
Controllerim 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.
## Api
### `controller(controllerClass)`
##### Arguments:
* **controllerClass**: any es6 class with a state member.
##### Returns:
* **Object: { create(), getInstance() }**: an object with two factory methods for getting a new controller instanceA controller is a plain Javascript class that holds a **state** and methods for manipulating the state.
All 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.The observers (React Components that you wrapped within `observer`) will react to any change in the state, even changes of deep nested properties.
#### `create(id?: string (default: 'globalInstance') )`:
Returns 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.
#### `getInstance(id?: string (default: 'globalInstance'))`:
Returns 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.#### controller Usage example:
```javascript
import {controller} from 'controllerim';class _AppController {
constructor() {
this.state = {totalNotesCount: 2};
}getTotalNotesCount() {
return this.state.totalNotesCount;
}increaseCounter() {
this.state.totalNotesCount++;
}
}export const AppController = controller(_AppController);
```Your React component will create an instance of the controller like this:
```javascript
import {AppController} from 'controllerim';class App extends React.Component {
constructor(props) {
super(props);
this.controller = AppController.create();
}render(){
{this.controller.getTotalNotesCount()}
this.controller.increaseCounter()}>click me
}
}
```### `useController(controllerInstance)`
Allows you to use controller inside a functional component. Note that you still have to wrap your functional component within `observer`.
```javascript
import React from 'react';
import {observer, useController} from 'controllerim';
import {FunctionalComponentController} from './TestComponentController';export const FunctionalComponent = observer(() => {
const controller = useController(FunctionalComponentController.create());
return (
{controller.getUserName()}
controller.changeUserName()}>click me
);
});
```
### `observer(ReactComponent)`To become reactive, every React component that uses a controller, should be wrapped within `observer`.
```javascript
import {observer} from 'controllerim';export const SomeSmartComponent = observer(class extends React.Component {
...
})
```### `store(storeClass)`
A store is just a global singleton controller that is not conceptually bound to any specific component.inside `AppStore.js`:
```javascript
import {store} from 'controllerim';class _AppStore {
constructor(){
this.state = {useName: 'bla'};
}getUserName() {
return this.state.userName;
}
}export const AppStore = store(_AppStore);
```Inside `component.jsx`:
```javascript
import React from 'react';
import {observer} from 'controllerim'
import {AppStore} from './AppStore';class SomeComponent extends React.Component {
render(){
{AppStore.getUserName()}// <== The component will re-render on any change in getUserName
}
}export default observer(SomeComponent);
```