All Projects → farwayer → Mobx Decorators

farwayer / Mobx Decorators

Several helper MobX decorators (setter, observe, save, ...)

Programming Languages

javascript
184084 projects - #8 most used programming language

Labels

Projects that are alternatives of or similar to Mobx Decorators

Gakki
🌼🌸 A React Native App for Mastodon. 一个由React Native编写的长毛象客户端App🦋
Stars: ✭ 120 (-24.05%)
Mutual labels:  mobx
React Mobx State Tree
Create React App with MobX State Tree, Styled Components and GraphQL
Stars: ✭ 127 (-19.62%)
Mutual labels:  mobx
Mobx Apollo
A MobX and Apollo Client integration utility.
Stars: ✭ 152 (-3.8%)
Mutual labels:  mobx
Gank
🦅 Gank api base △ next.js (react&ssr)
Stars: ✭ 122 (-22.78%)
Mutual labels:  mobx
React Transmission
React Transmission is an ongoing reimplementation of Transmission web interface.
Stars: ✭ 126 (-20.25%)
Mutual labels:  mobx
Xsm
State Management made eXtraordinarily simple and effective for Angular, React, and Vue
Stars: ✭ 138 (-12.66%)
Mutual labels:  mobx
S Mobx
轻量级mobx实现,仅供参考
Stars: ✭ 116 (-26.58%)
Mutual labels:  mobx
Mobx.dart
MobX for the Dart language. Hassle-free, reactive state-management for your Dart and Flutter apps.
Stars: ✭ 2,038 (+1189.87%)
Mutual labels:  mobx
Rnn Starter
🤹 Production-ready starter for your next React Native App! Powered by cli-rn, React Native Navigation, Expo, Reanimated 2, Notifications, Over-The-Air Updates, Mobx, Dark Mode, and Localization.
Stars: ✭ 127 (-19.62%)
Mutual labels:  mobx
Jjjkkk
🌚 Japanese adult video library app
Stars: ✭ 148 (-6.33%)
Mutual labels:  mobx
Apple Basket Redux
🍎 苹果篮子,一个微型的redux/mobx演示(附多版本)
Stars: ✭ 125 (-20.89%)
Mutual labels:  mobx
Eshoponcontainersddd
Fork of dotnet-architecture/eShopOnContainers in full DDD/CQRS design using my own patterns
Stars: ✭ 126 (-20.25%)
Mutual labels:  mobx
Skclusive.blazor.samples
Skclusive.Blazor.Samples
Stars: ✭ 144 (-8.86%)
Mutual labels:  mobx
React Eva
Effects+View+Actions(React distributed state management solution with rxjs.)
Stars: ✭ 121 (-23.42%)
Mutual labels:  mobx
Pul
PÜL - A carpooling app designed for students to help each other get more involved in their community.
Stars: ✭ 152 (-3.8%)
Mutual labels:  mobx
Mobx Preact
MobX bindings for Preact
Stars: ✭ 117 (-25.95%)
Mutual labels:  mobx
React Atom
A simple way manage state in React, inspired by Clojure(Script) and reagent.cljs
Stars: ✭ 133 (-15.82%)
Mutual labels:  mobx
Xbyjmusic
🎷🎸基于electron的跨平台 NeteaseMusic 桌面应用🎺🎻
Stars: ✭ 156 (-1.27%)
Mutual labels:  mobx
Tap The Number
A simple React-Native game for iOS
Stars: ✭ 153 (-3.16%)
Mutual labels:  mobx
Outline
The fastest wiki and knowledge base for growing teams. Beautiful, feature rich, and markdown compatible.
Stars: ✭ 13,833 (+8655.06%)
Mutual labels:  mobx

MobX decorators

Several helper MobX decorators

MobX 5 is not supported yet

Build Status Coverage Status

  1. Installation
  2. Decorators
  1. Changelog

Installation

npm install --save mobx-decorators

You also should use some transpiler (like babel).

npm install --save-dev @babel/plugin-proposal-decorators

Decorators

@setter

@setter
@setter(name)
@setter(name, constValue)
@setter(transformFn: value =>)
@setter(name, transformFn: value =>)

Create setter for property with setProperty or custom name.

If constValue provided this value will be set every time setter called. You can also provide transform function.

With transformFn function you can change value that will be set.

import {observable} from 'mobx'
import {setter} from 'mobx-decorators'
class User {
  @setter @observable loggedIn = false;
}

const user = new User();
user.setLoggedIn(true); // user.loggedIn = true
class User {
  @setter('updateLoggedIn')
  @observable loggedIn = false;
}

const user = new User();
user.updateLoggedIn(true); // user.loggedIn = true
class User {
  @setter('login', true)
  @setter('logout', false)
  @observable loggedIn = false;
}

const user = new User();
user.login(); // user.loggedIn = true
user.logout(); // user.loggedIn = false
class User {
  @setter(value => value && value.toUpperCase())
  @observable name;
}

const user = new User();
user.setName('Alice'); // user.name = 'ALICE'

@toggle

@toggle
@toggle(name)

Toggle boolean property (property = !property).

import {observable} from 'mobx'
import {toggle} from 'mobx-decorators'
class User {
  @toggle @observable loggedIn = false;
}

const user = new User();
user.toggleLoggedIn(); // user.loggedIn = !user.loggedIn
class User {
  @toggle('swapLoggedIn')
  @observable loggedIn = false;
}

const user = new User();
user.swapLoggedIn(); // user.loggedIn = !user.loggedIn

@observe

@observe(onChanged: change =>)
@observe(onChanged: change =>, invokeBeforeFirstAccess)

onChanged will be called after property change.

If invokeBeforeFirstAccess is true handler will be called one time before property first access (set or get).

More info can be found in mobx docs

import {observable} from 'mobx'
import {observe} from 'mobx-decorators'
class User {
  @observe(change => console.log(change.newValue))
  @setter @observable loggedIn = false;
}

const user = new User();
user.setLoggedIn(true); // console.log(true)
class User {
  @observe(change => console.log(change.newValue), true)
  @setter @observable loggedIn = false;
}

const user1 = new User();
const loggedIn = user.loggedIn; // console.log(false)
user1.setLoggedIn(true); // console.log(true)

const user2 = new User();
user2.setLoggedIn(true); // console.log(false)
                         // console.log(true)

@intercept

@intercept(onWillChange: change =>)

onWillChange will be called before property change. You can replace value or cancel change in handler.

More info can be found in mobx docs

import {observable} from 'mobx'
import {intercept} from 'mobx-decorators'
class User {
  @intercept(change => {
    change.newValue = 999;
    return change;
  })
  @setter @observable loginCount = 0;
}

const user = new User();
user.setLoginCount(1); // user.loginCount = 999;
class User {
  @intercept(change => null)
  @setter @observable loginCount = 0;
}

const user = new User();
user.setLoginCount(1); // user.loginCount = 0;

@_interceptReads

@_interceptReads(onRead: value =>)

interceptReads renamed in Mobx4 and look like will be deprecated

onRead will be called before property reading. You can transform value in handler.

More info can be found in mobx CHANGELOG

import {observable} from 'mobx'
import {_interceptReads} from 'mobx-decorators'
class User {
  @_interceptReads(value => value && value.toUpperCase())
  @observable name = 'Alice';
}

const user = new User();
console.log(user.name) // ALICE

@save

@save
@save({
  storage = defaultStorage(),
  storeName = store => store.storeName,
  serializer = {
    save: value => JSON.stringify(value),
    load: data => JSON.parse(data),
  },
  onLoaded = (store, property, value) => {},
  onSaved = (store, property, value) => {},
  onInitialized = (store, property, value) => {},
})
createSaveDecorator(baseOptions={})

(!) TypeScript: you can't use class property initializers (class F {prop = 1}) with @save decorator

@save decorator helps save and load observable value to/from permanent storage. Keep in mind @save is lazy decorator and loading will be started only after first property access. If you change property before or during loading than restored value will be ignored.

onLoaded callback will be called only if value is loaded from storage.
onSaved will be called after saving.
onInitialized will be called after loading attempt independent of the result.

By default values saved as json. In some cases (Date for example) you should provide serializer (see example with date).

You must define storeName property in store (see examples) or pass it as option. storeName option can be string or function.

Default storage is localStorage for browser, AsyncStorage for React Native and memory for other platforms. You can specify you own (localForage for example) by storage option. Storage must realize simple interface (functions are async or return Promise):

const MyStorage = {
  async getItem(key) {
    // return item
  },
  async setItem(key, value) {
    // save item
  }
}

If you need to pass the same options (storage for example) to @save decorator of several properties than you can use createSaveDecorator function.

import {observable} from 'mobx'
import {save, createSaveDecorator} from 'mobx-decorators'
class User {
  storeName = 'user';

  @save @observable loginCount;
}

const user = new User();
console.log(user.loginCount); // undefined
// @save will try to load loginCount from storage but
// loading is async (!) so value is still undefined here
class User {
  storeName = 'user';

  // storage contains 999 for loginCount property
  @save({
    onInitialized: (store, property, value) => {
      console.log(property, value); // 'loginCount', 999
      console.log(store.loginCount); // 999
    },
    onLoaded: (store, property, value) => {
      console.log(property, value); // 'loginCount', 999
      console.log(store.loginCount); // 999
    },
    onSaved: (store, property, value) => {
      console.log(property, value); // 1000
    }
  })
  @setter @observable loginCount;
}

const user = new User();
console.log(user.loginCount); // undefined, loading loginCount

// throw some time
console.log(user.loginCount); // 999

user.setLoginCount(1000); // 1000 will be saved to storage
class User {
  @save({
    storeName: 'user',
  })
  @observable loginCount;
  
  @save({
    storeName: 'group',
  })
  @observable group;
}

const user = new User();
console.log(user.loginCount); // undefined, loading loginCount
console.log(user.group); // undefined, loading group
class User {
  storeName = 'user';

  @save({
    serializer: {
      load: data => new Date(fromBSON(data)),
      save: value => toBSON(value),
    },
  })
  @observable lastLogin;
}

const user = new User();
console.log(user.lastLogin);
const mysave = createSaveDecorator({
  storage: MyOwnStorage,
  storeName: store => store.constructor.name,
});

class User {
  @mysave @observable loginCount;
  
  @save @observable name;
}

const user = new User();
console.log(user.loginCount);
const mysave = createSaveDecorator({
  storage: MyOwnStorage,
  storeName: 'user',
});

class User {
  @mysave({
    onInitialized: () => console.log('initialized')
  })
  @observable loginCount;
  
  @save @observable name;
}

const user = new User();
console.log(user.loginCount);

@allObservable

@allObservable
@allObservable({
  only,
  except = [],
})

Class decorator that makes all properties observable. Use only for whitelisting properties and except for blacklisting.

import {allObservable} from 'mobx-decorators'
@allObservable
class User {
  name = 'unknown';
  loginCount = 0;
}
@allObservable({only: ['loginCount']})
class User {
  name = 'unknown';
  loginCount = 0;
}
@allObservable({except: ['name']})
class User {
  name = 'unknown';
  loginCount = 0;
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].