# Redux -> Eventrix

The transition from redux to eventrix is ​​not that hard. Some things are named differently, but they work similarly. The following examples show what the code looks like using Redux and Eventrix.

### Store

Initializing store and core elements is almost the same. **Eventrix doesn't need middlewares** unlike redux. Eventrix can handle asynchronous actions itself.

{% tabs %}
{% tab title="Redux" %}
{% code title="store.js" %}

```javascript
import { createStore, applyMiddleware } from "redux";
import thunk from 'redux-thunk'
import reducers from "./reducers";

export default createStore(reducers, applyMiddleware(thunk));
```

{% endcode %}
{% endtab %}

{% tab title="Eventrix" %}
{% code title="store.js" %}

```javascript
import { Eventrix } from "eventrix";
import receivers from "./receivers";

const initialState = {};
export default new Eventrix(initialState, receivers);
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Reducer

Instead of the **reducer** in **eventrix, it is receiver**. It differs significantly from the **reducer**. **Receiver** is responsible for receiving the event and has the ability to **modify the state using stateManager**. **StateManager** has access to the entire **state**, so it can download and modify any state. If you need to get some data from API, you can do it in receiver and return promis&#x65;**.**

{% tabs %}
{% tab title="Redux" %}
{% code title="reducers.js" %}

```javascript
import { combineReducers } from "redux";

const counter = (state = [], action) => {
    switch (action.type) {
        case `increaseCounter`:
            return counter + 1;
        case `reduceCounter`:
            return counter - 1;
        default:
            return state;
    }
};

export default combineReducers({ counter });
```

{% endcode %}
{% endtab %}

{% tab title="Eventrix" %}
{% code title="receivers.js" %}

```javascript
import { EventsReceiver } from "eventrix";

const counterReceiver = new EventsReceiver(
    ['increaseCounter', 'reduceCounter'],
    (eventName, eventData, stateManager) => {
        const counter = stateManager.getState('counter');
        if (eventName === 'increaseCounter') {
            return stateManager.setState('counter', counter + 1);
        }
        stateManager.setState('counter', counter - 1);
    }
);

export default [counterReceiver];
```

{% endcode %}
{% endtab %}

{% tab title="Eventrix (good practices)" %}
{% code title="receivers.js" %}

```javascript
import { EventsReceiver } from "eventrix";

const increaseCounterReceiver = new EventsReceiver(
    'increaseCounter',
    (eventName, eventData, stateManager) => {
        const counter = stateManager.getState('counter');
        stateManager.setState('counter', counter + 1);
    }
);

const reduceCounterReceiver = new EventsReceiver(
    'reduceCounter',
    (eventName, eventData, stateManager) => {
        const counter = stateManager.getState('counter');
        stateManager.setState('counter', counter - 1);
    }
);

export default [increaseCounterReceiver, reduceCounterReceiver];
```

{% endcode %}
{% endtab %}

{% tab title="Eventrix - async" %}
{% code title="receivers.js" %}

```javascript
import axios from 'axios';
import { EventsReceiver } from "eventrix";

const fetchCounterReceiver = new EventsReceiver(
    'fetchCounter',
    (eventName, eventData, stateManager) => {
        const { counterId } = eventData; 
        return axios.get(`https://someApi.com/counter/${counterId}`).then(({ data }) => {
            stateManager.setState('counter', data);
        });
    }
);

export default [fetchCounterReceiver];
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Provider

Provider does not differ only in names.

{% tabs %}
{% tab title="Redux" %}
{% code title="App.jsx" %}

```jsx
import React from "react";
import { Provider } from "react-redux";
import store from "./store";
import Toolbar from "./components/Toolbar";
import Counter from "./components/Counter";

export default function App() {
    return (
        <Provider store={store}>
            <div>
                <Counter />
                <Toolbar/>
            </div>
        </Provider>
    );
}
```

{% endcode %}
{% endtab %}

{% tab title="Eventrix" %}
{% code title="App.jsx" %}

```jsx
import React from "react";
import { EventrixProvider } from "eventrix";
import eventrix from "./store";
import Toolbar from "./components/Toolbar";
import Counter from "./components/Counter";

export default function App() {
    return (
        <EventrixProvider eventrix={eventrix}>
            <div>
                <Counter />
                <Toolbar/>
            </div>
        </Provider>
    );
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Dispatch

Redux handles the **actions** we pass to **dispatch**. Eventrix has **events** that are emitted by **emit. Events**, unlike **actions**, can be received by components if they register to them. This is how we enable communication between components. Method **emit** returns a promise waiting for all async **receivers** and **listeners** to be called. Thanks to this, you can handle the end of an **event** in the component.

{% tabs %}
{% tab title="Redux" %}
{% code title="components/Toolbar.jsx" %}

```jsx
import React, { useCallback } from "react";
import { useDispatch } from "react-redux";

const Toolbar = () => {
    const dispatch = useDispatch();
    const increaseCounter = useCallback(() => {
        dispatch({ type: 'increaseCounter' });
    }, [dispatch]);
    return (
        <button onClick={increaseCounter}>Increase counter</button>
    );
};

export default Toolbar;
```

{% endcode %}
{% endtab %}

{% tab title="Eventrix" %}
{% code title="components/Toolbar.jsx" %}

```jsx
import React, { useCallback } from "react";
import { useEmit } from "eventrix";

const Toolbar = () => {
    const emit = useEmit();
    const increaseCounter = useCallback(() => {
        emit('increaseCounter');
    }, [emit]);
    return (
        <button onClick={increaseCounter}>Increase counter</button>
    );
};

export default Toolbar;
```

{% endcode %}
{% endtab %}

{% tab title="Eventrix - async" %}
{% code title="components/Toolbar.jsx" %}

```jsx
import React, { useCallback } from "react";
import { useEmit } from "eventrix";

const Toolbar = () => {
    const emit = useEmit();
    const fetchCounter1 = useCallback(() => {
        const counterId = 1;
        emit('fetchCounter', { counterId }).then(() => {
            console.log('counter fetched');
        });
    }, [emit]);
    return (
        <button onClick={fetchCounter1}>fetch counter 1</button>
    );
};

export default Toolbar;
```

{% endcode %}
{% endtab %}
{% endtabs %}

### State

Redux handles state change in components with **useSelector**. Eventrix handles this with **useEventrixState**. The main difference is in use and action. In terms of operation, selectors are called whenever **dispach** is called and redux checks if the component should rerender. Eventrix rerender component only when the change relates to the state for which the component has registered.

{% tabs %}
{% tab title="Redux" %}
{% code title="components/Counter.jsx" %}

```jsx
import React from "react";
import { useSelector } from "react-redux";

const counterSelector = (state) => {
    return state.counter;
};

const Counter = () => {
    const counter = useSelector(counterSelector);

    return <div>{counter}</div>;
};

export default Counter;
```

{% endcode %}
{% endtab %}

{% tab title="Eventrix" %}
{% code title="components/Counter.jsx" %}

```jsx
import React from "react";
import { useEventrixState } from "eventrix";

const Counter = () => {
    const [counter, setCounter] = useEventrixState('counter');

    return <div>{counter}</div>;
};

export default Counter;
```

{% endcode %}
{% endtab %}
{% endtabs %}
