Cerebral - Part 3, Signals and Actions
Tags: cerebraljs, javascript, react
Published: 2017-05-01 14:15:08

---
title: Cerebral - Part 3, Signals and Actions
published: true
description: Getting your code into shape with signals and actions.
tags: cerebraljs, javascript, react
canonical_url: https://blog.reflog.me/post/cerebral-part-3-signals-and-actions
---


# Refactoring

In this post we'll extend our previous counter example by refactoring it a little bit.

Let's recall how the main controller looked before:


```javascript

import {Controller} from 'cerebral'

function increase ({state}) {
  state.set('count', state.get('count') + 1)
}

function decrease ({state}) {
  state.set('count', state.get('count') - 1)
}

const controller = Controller({
  state: {
    count: 0
  },
  signals: {
     onIncrease: [increase],
     onDecrease: [decrease]
  }
})

```

Let's try to understand what's happening here exactly.	
a. Inside the controller we define two signals: onIncrease and onDecrease.
b. For each signal, we reference a function that will handle that signal
c. That function (increase/decrease) will receive a parameter called *'context'*. It will contain all sorts of useful information, but since all we need from it is our *'state'*, we do ES6 'desctructuring' by applying `{state}` as it's parameter

Now, let's refactor this code a little bit, since both *increase* and *decrease* functions basically have the same code. How can we do that?

Here's one way: Let's pass a parameter to the signal, which will select the direction of counter change. This way we'll be able to use the same function for both cases.

Now our code will look like this:

```javascript

import {Controller} from 'cerebral'

function changeCounter({props, state}){
  state.set("count", state.get("count") + props.param);
}

const controller = Controller({
  state: {
    count: 0
  },
  signals: {
     changeCounter
  }
})

export default controller

```

There's two things to notice here:
a. We now destructure two parameters to our handler: `{state, props}`. The `props` parameter is an object containing all paramers passed down to the signal
b. We no longer need two signals!

Now that we changed the controller, here's how the component will look:

```javascript

import React from 'react'
import {connect} from 'cerebral/react'
import {state, signal} from 'cerebral/tags'
export default connect({
  count: state`count`,
  changeCounter: signal`changeCounter`
},
function App ({ changeCounter, count }) {
  return (
   <div>
    <button onClick={() => changeCounter({param:1})}>+</button>
    {count}
    <button onClick={() => changeCounter({param:-1})}>-</button>
  </div>
  )
})


```

Nice and clean!

# Signal Chains

Did you notice that when we defined the signal handlers, they were initially passed as an array? The reason for that is a neat one - Cerebral's signals trigger chains of actions.

This awesome feature allows you to group together several actions that need to happen one after the other when a certain signal is triggered.

Let's see a small example of how it's done.

I'm going to add a log action that will write to console the new value of the counter on each change.

```javascript

import {Controller} from 'cerebral'

function changeCounter({props, state}){
  state.set("count", state.get("count") + props.param);
}

function logAction({state}){
  console.log(`counter changed to ${state.get("count")}`)
}

const controller = Controller({
  state: {
    count: 0
  },
  signals: {
     changeCounter: 
     [
       changeCounter, 
       logAction
     ]
  }
})

export default controller

```

Now, each time you trigger a change - you'll see a nice log message!

The nice thing about actions, signals and chains is that they are all visible in the Debugger. Take a look:

![DEBUGGER](http://blog.reflog.me//uploads/2017/04/29/dbg5.png)

Here's the full project on [WebpackBin](https://www.webpackbin.com/bins/-KitMr9dCRc49A28ha6F)

In the next part of these series, I'll discuss the next amazing Cerebral feature - '**tags**'.