# add

The function `add` is responsible for building your wrapper to actually do some stuff. Every `add` returns the instance, so you can nicely chain your additions.

Every `add`-call only takes an object which itself only has a single root-key, thus limiting each addition to one specific task. Here is a list of all possible add-params:

## add({ initState: })

Define a default state for redux. Has to be provided. Same as in every standard reducer used with redux.

```javascript
// Example:

import ReduxWrapper from "redux-sands";

const wrapper = new ReduxWrapper({ called: "demo" });
wrapper.add({ initState: { count: 0 } });

//...
```

## add({ component: })

Define the React-component for this wrapper. Not necessary if already done during init.

```javascript
// Example (using ES6):

import ReduxWrapper from "redux-sands";
import component from "./component";

const wrapper = new ReduxWrapper({ called: "demo" });
wrapper.add({ initState: { count: 0 } });
wrapper.add({ component });

//...
```

## add({ reducer: })

{% hint style="info" %}
**This call has a shorthand version,** [**see next listing**](#add-reducername)**.**

If you want to, you can use this extensive version, but the short one is recommanded, which saves you the `reducer` keyword and in case it's a plain reducer without saga, also saves the `fn` key.
{% endhint %}

Add a new reducer. You define a reducer by providing its name as the next key after `reducer`. The name-key itself has possible two children:

{% tabs %}
{% tab title="fn" %}
The reducer function, just as you know from standard redux.

* takes `(state, action)` as function-params
* has to return a state-copy, as it's usually done by redux

```javascript
// Example:

import ReduxWrapper from "redux-sands";
import component from "./component";

const wrapper = new ReduxWrapper({ called: "demo", component });

wrapper.add({
    reducer: {
      update: {
        fn: (state, action) => ({ ...state, ...action })
      }
    }
  })
```

{% endtab %}

{% tab title="withSaga" %}
Provide an additional saga-listener.

* has only one children, which itself is a key, too: Represents one of saga's effect-functions, such as \`takeEvery\`, provided as strnig. The mapping to the correct function gets done by the wrapper
* the effect-name-key has the usual saga-generator as child

{% hint style="success" %}
The action passed to the generator contains a param `result`. You have to provide its contents to `put`, else the saga can't be handled correctly. Specifically, `result` contains the param `type`, which represents the reducer's type, thus enabling the reducer to be called after the dispatch.

Furthermore, the `action` contains all saga-effects required to actually work with saga.
{% endhint %}

{% hint style="info" %}
Currently, only `takeEvery` is supported. Other saga effects will be included soon.
{% endhint %}

### Example (long version)

```javascript
import ReduxWrapper from "redux-sands";
import component from "./component";

const wrapper = new ReduxWrapper({ called: "demo", component });

wrapper.add({
  reducer: {
    update: {
      fn: (state, action) => ({ ...state, ...action }),
      withSaga: {
        takeEvery: function*(action) {
          const { result, put, url } = action;
          try {
            const data = yield fetch(url);
            yield put({ ...result, data });
          } catch (e) {
            yield put({ ...result, error: e });
          }
        }
      }
    }
  }
});
```

### Example (shorter version)

```javascript
import ReduxWrapper from "redux-sands";
import component from "./component";

const wrapper = new ReduxWrapper({ called: "demo", component });

wrapper.add({
  reducer: {
    update: {
      fn: (state, action) => ({ ...state, ...action }),
      withSaga: {
        takeEvery: function*(action) {
          const { result, put, url } = action;
          try {
            const data = yield fetch(url);
            yield put({ ...result, data });
          } catch (e) {
            yield put({ ...result, error: e });
          }
        }
      }
    }
  }
});
```

{% endtab %}
{% endtabs %}

## **add({ \[reducerName]: })**

> Shortest version to add a reducer (and optional saga).

When none of the keys above is provided, it's assumed you're providing a reducer in the shorthand version. Therefore, the key describes the reducer name and its child represents the reducer-functions itself. This is shortest way possible to add a reducer.

#### Simple reducer

```javascript
import ReduxWrapper from "redux-sands";
import component from "./component";

const wrapper = new ReduxWrapper({ called: "demo", component });

wrapper.add({ update: (state, action) => ({ ...state, ...action }) });
wrapper.add({ update: (state, { count }) => ({ ...state, count }) });

//...

export default wrapper.connection;
export const reducer = wrapper.reducer
```

#### Reducer with saga

```javascript
//...

wrapper.add({
  update: {
    fn: (state, { count }) => ({ ...state, count }),
    withSaga: {
      takeEvery: function*(action) {
        const { result, put } = action;
        yield put({ ...result });
      }
    }
  }
});

//...

export default wrapper.connection;
export const reducer = wrapper.reducer
export cons saga = wrapper.saga;
```
