CerebralJS
Tags: cerebraljs, react, javascript, redux
Published: 2017-04-25 08:45:57

---
title: CerebralJS
published: true
cover_image: 
description: Introduction to the new hotness in the world of React state management
tags: cerebraljs, react, javascript, redux
canonical_url: https://blog.reflog.me/post/cerebraljs/
---

I want to preface this post with the following disclaimer:


<blockquote>I am not a fan of Redux. It became a de-facto standard in state management of React apps and seems to be working great for a lot of people, but I find it to be very verbose and hard to work with.</blockquote>


Ok. Now that it's out of the way, let's see what else exists in the world today that can help us maintain our application state **and** keep our sanity.


The project I'm going to discuss is called [Cerebral](http://cerebraljs.com/docs/get_started/) and it was created byÂ  Christian Alfoni,Â Aleksey Guryanov and many others specifically to address the downsides of Flux and Redux.


I highly recommend reading Christian's [introduction article](http://www.christianalfoni.com/articles/2017_03_19_Cerebral-2) to Cerebral 2 to get a sense of the main differences between the frameworks.


In this post I'm going to make a small introduction to Cerebral by comparing the basic Counter example written using Redux to one in Cerebral.


In upcoming posts I'll start introducing more advanced concepts and that's where things will start getting really fun :)


## Redux Counter


A simple Redux application consists of:


### Entry point


```javascript


import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import counterApp from './reducer'
import Counter from './Counter'

let store = createStore(counterApp)

render(
  <Provider store={store}>
    <Counter />
  </Provider>,
  document.getElementById('root')
)


```


### Reducer


```javascript


export default (state = 0, action) => {
  switch (action.type) {
    case 'INCREASE':
      return state + 1
    case 'DECREASE':
      return state - 1
    default:
      return state
  }
}


```


### Main component


```javascript


import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import { increase, decrease } from './actions'

const mapStateToProps = (state) => {
  return {
    count: state
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onIncrease: () => {
      dispatch(increase())
    },
    onDecrease: () => {
      dispatch(decrease())
    }
  }
}

const Counter = ({ onIncrease, onDecrease, count }) => (
  <div>
    <button onClick={onIncrease}>+</button>
    {count}
    <button onClick={onDecrease}>-</button>
  </div>
)

Counter.propTypes = {
  onIncrease: PropTypes.func.isRequired,
  onDecrease: PropTypes.bool.isRequired,
  count: PropTypes.string.isRequired
}


export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Counter)


```


### Actions


```javascript


export const increase = () => {
  return {
    type: 'INCREASE'
  }
}

export const decrease = () => {
  return {
    type: 'DECREASE'
  }
}

```


_And it works like follows_: you define your actions separately, then define the 'reaction' to those actions in the reducer, i.e. how the state will be affected. Then you connect the component to the state.


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



## Cerebral Counter

A simple Cerebral application consists of:

### Entry point

```javascript


import React from 'react'
import {render} from 'react-dom'
import {Container} from 'cerebral/react'
import controller from './controller'
import App from './App'

render((
  <Container controller={controller}>
    <App />
  </Container>
), document.querySelector('#app'))

```

### Controller

```javascript


import {Controller} from 'cerebral'
import {set} from 'cerebral/operators'
import {state, string} from 'cerebral/tags'

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]
  }
})

export default controller

```

### Main component

```javascript


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


```


_And it works like follows_: you define a controller that contains a state and a list of signals that are handled by it. Then you connect a component to specific state elements and signals and use them directly.


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


As you can see there are quite a few differences here:

1. You don't need to pre-define actions.
2. There is no "string" magic
3. Code is much less verbose

And what you've seen here is just the absolute tip of the iseberg. Cerebral provides **so much more**! I hope to get into all of it in upcoming posts.