npm package: @hookcompany/rematch-decorators
Description: ️❄️️ Use rematch, but in a more elegant way.
Author: Hook Company Team
Latest version: 1.0.11

# Rematch Decorators

## ❄️ Use rematch, but in a more elegant way.

[![NPM version](https://badge.fury.io/js/%40hookcompany%2Frematch-decorators.png)](http://badge.fury.io/js/%40hookcompany%2Frematch-decorators)

[![Npm Downloads](https://nodei.co/npm/@hookcompany%2Frematch-decorators.png?downloads=true)](https://nodei.co/npm/@hookcompany%2Frematch-decorators.png?downloads=true)

## Getting Started

Use npm:

```sh
npm install --save-dev babel-plugin-transform-decorators-legacy
npm install --save @hookcompany/rematch-decorators
```

Or use yarn:

```sh
yarn add --dev babel-plugin-transform-decorators-legacy
yarn add @hookcompany/rematch-decorators
```

### Step 1: Babel Configuration

You have to configure decorators plugin on babelrc. This is an exemple on react-native babelrc, but work wherever you want to use.

#### .babelrc

```json
{
  "presets": ["react-native"],
  "plugins": ["transform-decorators-legacy"]
}
```

### Step 2: Init

**init** is only a rematch init function wrapper, and repass all arguments same as rematch init function receive. And you can pass a seamless-immutable instance on the second parameter to create the initial values with it.

#### index.js

```js
import init from '@hookcompany/rematch-decorators';
import Store from './store';

export default init({
  models: { count: new Store() }
});
```

Or passing seamless-immutable instance:

#### index.js

```js
import init from '@hookcompany/rematch-decorators';
import Immutable from 'seamless-immutable';
import Store from './store';

export default init({
  models: {
    count: new Store()
  }
}, Immutable);
```

### Step 3: Models

The rematch **model** brings together state, reducers, async actions & action creators in one place. But with rematch-decorator you can do the same thing using ES6 class with decorators.

#### count-store.js

```js
import { state, reducer, effect } from '@hookcompany/rematch-decorators';

export default class Store {
  @state counter = 0;

  @reducer
  increment = (actualState, payload) => ({
    ...actualState,
    counter: actualState.counter + payload
  });

  @effect
  incrementAsync = dispatch => async payload => {
    await new Promise(resolve => setTimeout(resolve, 1000));
    dispatch.count.increment(payload);
  }
}
```

You can use shortEffect decorator instead effect decorator and use dispatch function that is in class instance instead currying with dispatch argument.

#### count-store.js

```js
import { state, reducer, shortEffect } from '@hookcompany/rematch-decorators';

export default class Store {
  @state counter = 0;

  @reducer
  increment = (actualState, payload) => ({
    ...actualState,
    counter: actualState.counter + payload
  });

  @shortEffect
  incrementAsync = async payload => {
    await new Promise(resolve => setTimeout(resolve, 1000));
    this.dispatch.count.increment(payload);
  }
}
```

There is another way to use rematch-decorators, but you cannot use this way with rematch-decorators init function, like this:

```js
import { init } from '@rematch/core';
import { model, state, reducer, shortEffect } from '@hookcompany/rematch-decorators';

class Store {
  @state counter = 0;

  @reducer
  increment = (actualState, payload) => ({
    ...actualState,
    counter: actualState.counter + payload
  });

  @shortEffect
  incrementAsync = async payload => {
    await new Promise(resolve => setTimeout(resolve, 1000));
    this.dispatch.count.increment(payload);
  }
}

export default init({
  models: {
    count: model(new Store())
  }
});
```

### Step 4: Usability

You can use the rest same as rematch usability.