Immutable.js and React



Immutable.js and React

0 0


immutablejs-and-react

Vienna ReactJS talk "ImmutableJS and React" slides

On Github 25th-floor / immutablejs-and-react

Immutable.js and React

S. Oestreicher @thinkfunctional A. Sharif @sharifsbeat

What we do

25th-floor

  • Agile, Scrum, Self-organization, Team Culture
  • React, AngularJS
  • XP, Pair, Mob Programming etc.
  • Consulting, Workshops etc.

Why Immutability

  • Problems with AngularJS
  • Data being mutated, hard to control and debug
  • State everywhere
  • Side effects out of control
  • Data consistency nightmare

Basics

var foo = 'Some String';
var bar = foo.substr(1, 3);

JavaScript Strings are immutable.

Basics

Mutability is hard

function top(n, xs) {
  xs.sort().reverse();
  return xs.slice(0, n);
}

// somewhere else
let xs = [4, 1, 3, 2, 5];
let top3 = top(3, xs);
// oops, xs has been changed!
// Do I need to make a copy? Should "top" make a copy?

Basics

Mutability is hard

let now = moment();
let startOfWeek = now.startOf('week');
let endOfWeek = now.endOf('week');

now.format('YYYY-MM-DD');          // => 2015-11-07
startOfWeek.format('YYYY-MM-DD');  // => 2015-11-07
endOfWeek.format('YYYY-MM-DD');    // => 2015-11-07

// we have to remember to make a copy every time!
let now = moment();
let startOfWeek = now.clone().startOf('week');
let endOfWeek = now.clone().endOf('week');

Basics

  • The support of an efficient change detection by using === operator to compare objects.
  • If the objects are identical you can be sure that nothing has changed.

Structural Sharing

"Purely functional tree, after" by VineetKumar at English Wikipedia

Immutable.js / API

Immutable.fromJS()
Immutable.fromJS([{a:1}, {b:2}])
get()
let map = Immutable.fromJS({foo: {bar: 1}});
map.get('foo').get('bar'); //instead of map.foo.bar 
Immutable.is()
Immutable.is(this.props.cols, nextProps.cols);

Immutable.js / API

updateIn()
rows.updateIn([row, 'cols', col, 'active'], active => !active);
setIn()
rows.setIn([row, 'cols', col, 'active'], false);
mergeDeep()
var x = Immutable.fromJS({a: { x: 10, y: 10 }, b: { x: 20, y: 50 } });
var y = Immutable.fromJS({a: { x: 2 }, b: { y: 5 }, c: { z: 3 } });
x.mergeDeep(y) // {a: { x: 2, y: 10 }, b: { x: 20, y: 5 }, c: { z: 3 } }

Immutable.js / API

All the usual suspects

  • filter
  • map
  • reduce
  • some
  • every
  • groupBy
  • find

React

shouldComponentUpdate

The secret sauce of why ClojureScript React wrappers are faster than vanilla React.

React

PureRendererMixin

Useful, but you should prefer your own implementation to leverage Immutable.is

var a = Immutable.List([1,2]);
var b = Immutable.List([1,2]);
a === b; // => false
Immutable.is(a, b); // => true

React Flux, Redux

Serialization

var map = Immutable.Map();

map = map.set(Immutable.Map({foo:'bar'}), 'foobar');

map.get(Immutable.Map({foo:'bar'}));
// => 'foobar'

map.toJSON();
// => {"[object Object]": "foobar"}

// sad :-(

Transit.js

writer

function handle(what) {
  return transit.makeWriteHandler({
    tag: v => what,
    rep: v => v,
    stringRep: v => null
  });
}

var writer = transit.writer("json-verbose", {
  handlers: transit.map([
    Immutable.List, handle('array'),
    Immutable.Map, handle('map')
  ])
});

Transit.js

reader

var reader = transit.reader("json", {
    arrayBuilder: {
        init: function(node) { return Immutable.List().asMutable(); },
        add: function(ret, val, node) { return ret.push(val); },
        finalize: function(ret, node) { return ret.asImmutable(); },
        fromArray: function(arr, node) {
            return Immutable.List.from(arr);
        }
    },
    mapBuilder: {
        init: function(node) { return Immutable.Map().asMutable(); },
        add: function(ret, key, val, node) { return ret.set(key, val); },
        finalize: function(ret, node) { return ret.asImmutable(); }
    }
});

Pros and Cons

When?

  • Simple change detection
  • No defensive copies
  • Trivial undo/redo
  • Share data freely

Pros and Cons

What are the trade offs?

  • Mixed mutable and immutable is a headache
  • ImmutableJS doesn’t play with others (e.g. lodash)
  • Won’t help with other mutable libraries (e.g. momentjs)

Demo

Demo Time!

Q&A

Thanks

“No man can step into the same river twice.”
Immutable.js and React S. Oestreicher @thinkfunctional A. Sharif @sharifsbeat