You Might Not Need Redux

08 May 2017

Whenever I start a new front end project using React, I get a lot of helpful suggestions like “Use Redux, it’s great!” or “Use Mobx, it’s great!” or “Use Redux Saga, it’s great!”.

“But why would I need Redux (or Mobx or Redux Saga, or whatever state management library that is in vogue as you read this)?” I ask.

“It’s the current paradigm,” (or something along those lines) is a frequent answer, which is just another way of saying “All the cool kids are doing it.” Which is not an answer to the question “why?”

So why do you want to use Redux?

In order to understand why you need Redux, you need to understand why Flux Architecture was needed. In order to understand Flux Architecture, you need to understand why two-way bindings and MVC architecture was needed. In order to understand two-way bindings and MVC, you need to understand plain old DOM manipulations.

So let’s start there.

Plain old DOM manipulation

This is how we used to do it “back in my day”:

var xhr = new XMLHttpRequest();
 
xhr.onreadystatechange = function() {
  if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
    document.getElementById('answer').value = xhr.responseText;
  }
}
xhr.open('GET', 'http://foo.com/bar', true);
xhr.send(null);

As you can see, the application code will get out of hand very quickly.

DOM manipulation with jQuery

When jQuery came along, it got a little better:

$.get('http://foo.com/bar', function(data) {
  $("#answer").value(data);
});

This made the code a little less verbose, but the fundamental problem remained: your data querying, business logic and your UI rendering (DOM manipulations) code were all mixed in together. Also, you were hand-coding the changes to the view in response to the changes to your data.

MVC with two-way data binding

Next, we came up with the idea of views bound to data in models in such a way that when controllers change the model, the views “react” and update themselves. And when the user updates the views, the model reacts and updates itself. MVC with two-way data bindings was born.

Here’s an example using Angular (I’ve omitted the Ajax call here and only demonstrated the 2-way data binding between $scope.answer and the answer input field.

<div ng-app="QAApp" ng-controller="QCtrl">
  Answer: <input id="answer" type="text" ng-model="answer"><br>
  <br>
  Answer is: 
</div>
 
<script>
var app = angular.module('QAApp', []);
app.controller('QCtrl', function($scope) {
    $scope.answer = "Your answer";
});
</script>

So now we cleanly separated the view from the data and the logic. All good, right? Not quite. As applications got larger and models were bound to multiple views and were manipulated by multiple controllers, it became increasingly difficult to follow the execution of the app from the point of data change to the view. It could also potentially result in loops – a model updates the view, which updates another model, which updates the view… so on and so forth. Debugging was a nightmare for large applications with complex logic.

React

Facebook’s React.js library came with one-way data bindings – changes to the data (or “props”) caused the view to react and update itself. But changes to the view did not affect data. Instead, such changes had to be notified as events, which the application was expected to capture and change the data. In other words, “data flows down, events flow up”. But React.js, being just a view library, was silent about how to do this. Only later did Facebook’s developers come up with Flux Architecture. This began a blizzard of competing Flux libraries (names like “Flummox”, “Marty”, “McFly”, “Alt”, “Reflux”, “Fluxxor” come to mind). Redux, a reducer function based library, seem to have won the war. And that is how we came to be using Redux for the majority of our React apps.

Here’s a sufficiently abstract representation of Flux: https://github.com/facebook/flux/tree/master/examples/flux-todomvc Redux is not too dissimilar.

If not Redux, then what?

Say you’re to write an app for a simple Todo list. Now assume that the developers of the Todo application backend have provided you with a ready-made JavaScript client that is a very convenient wrapper around the API – the client object encapsulates all the logic, state and fetch actions that are needed to cater to a front end. Then all you need is to map your react component props to data from that client and component event handlers to functions in the client. For asynchronous operations, you subscribe and listen to events emitted by the client.

It kind of sounds like Flux all over again, but note the differences:

import Todo from 'todo-client';
  
// initialize todo application client
// this encapsulate all client side state, actions, network calls and logic
Todo.init({
  url: 'http://localhost',
  username: 'bob'
});
  
// stateless view template
// this has only props, no state
const TodoList = (list) => {
};
  
// wrap stateless template around a stateful 'wiring' component
// this has only state, no props
class TodoListView extends React.Component {
  constructor(props) {
    this.setTodos = this.setTodos.bind(this); // would could metaprogram this
    this.onClickNewItem = this.onClickNewItem.bind(this);
  }
 
  componentWillMount() {
    setTodos({list: Todo.getTodoList()}); // initial state
    Todo.on(Todo.events.TODOS_UPDATED, this.setTodos); // subscribe to further updates to state
  }
  
  componentWillUnmount() {
    Todo.off(Todo.events.TODOS_UPDATED, this.onTodosUpdated);
  }
  
  setTodos(list) {
    this.setState({ list: list });
  }
 
  onClickNewItem() {
    Todo.createDraftItem();
  }
  render() {
    return (<TodoList list={this.state.list} onClickNewItem={this.onClickNewItem} />);
  }
}
  
ReactDOM.render(<TodoListView/>, document.getElementById('todo'));

That’s it – a stateless component wrapped around a state-only component that calls an business API client. Much of what we put in actions and reducers are encapsulated inside the business API, along with network calls and business logic. The stateless components only contain HTML/JSX and the stateful wrapper component only contains code that wires the stateless component to the application client. This makes the front end extremely thin. I’d actually suggest that the application API client be developed and maintained as a completely separate codebase from the front end.

Deceptively simple, is it not?

Donald Knuth is the root of all evil

23 Jul 2015

Trying to optimize your code before you know which parts of it consume the most time and resources, or worse yet, doing so even before you know whether your code runs slowly at all, is bad. But so is dismissing preperation, precaution and diligence with a pithy one-liner you picked up from a paper you haven’t read, written by an author whose original meaning you don’t seem to have deciphered.

I speak, of course, of the notorious:

“Premature optimization is the root of all evil.” - Donald Knuth

Read more...

Are we heading for Darmok?

20 Jul 2015

When I recently came across a news article 1 (a distinction the piece of writing hardly deserves) that began the description of the complex communication process between the New Horizons space probe and Earth with the heading “A 3-Billion-Mile Snapchat”, I had to ask myself: is this what journalism is now? And then I was reminded of Darmok.

Darmok 2 was a notable episode of the science fiction TV series Star Trek: The Next Generation. The Enterprise encounters an alien species–as they usually do on a weekly basis–whose utterances don’t quite translate well when run through the ship’s Universal Translator. The aliens, called the Tamarians, are heard to utter such seeming nonsense as “Darmok and Jalad at Tanagra”(now a famous phrase) and “Temba, his arms wide”. It is later discovered that the species verbalize concepts not by assigning words directly to them, but by using metaphors (or more accurately analogies 3) that represent the concept.

Read more...

Why you will never escape ads by paying for content

19 Jul 2015

The Internet is full of ads. More than ever. So much so that the actual information the Internet was meant to exchange–news, articles, posts, books, lessons, conversations, data–are collectively called “content”, a word that, when used by advertisers, almost means “filler”.

Here’s why I believe you will not escape ads by paying for your content: people who can afford to pay for content are people with money, or people with buying power, in other words, the exact same people advertisers look to target. The more buying power you demonstrate, the more advertisers will target you. So the more you pay to keep ads away, the more advertisers will pay to put them back in. With the way the world currently works, selling ads, it seems, will always be more profitable than selling content.

Read more...

An extension to Hofstadter's modes of thinking

03 Jun 2015

In Douglas Hofstadter’s classic Godel, Escher and Bach: An Eternal Golden Braid 1, “MU” refers to both the puzzle he uses to introduce the idea of formal systems, as well as the two modes of thinking humans use with such systems: M-Mode is the mechanical mode, I-Mode is the intelligent mode.

Before I introduce two more modes – D-Mode, or Deep Mode and S-Mode or Shallow Mode – let’s look at the puzzle and how it relates to thinking about problems:

Read more...

Reading - Geeks, MOPs, and sociopaths in subculture evolution

31 May 2015

Geeks, MOPs, and sociopaths in subculture evolution, David Chapman, 2015: discusses how once successful and thriving subcultures die at the hands of what he calls “MOPs” (members of public) and “sociopaths”.

Exerpts

Before there is a subculture, there is a scene. A scene is a small group of creators who invent an exciting New Thing—a musical genre, a religious sect, a film animation technique, a political theory. Riffing off each other, they produce examples and variants, and share them for mutual enjoyment, generating positive energy.

The new scene draws fanatics. Fanatics don’t create, but they contribute energy (time, money, adulation, organization, analysis) to support the creators.

If the scene is unusually exciting, and the New Thing can be appreciated without having to get utterly geeky about details, it draws mops.

A related article on Less Wrong, via the Hacker News discussion: Well-Kept Gardens Die By Pacifism

Index cards as an Evernote alternative

30 May 2015

After 20 years of fiddling with various electronic formats to keep notes and record my thoughts (which I have been doing since I was 15), I’ve finally returned to where I started: pen-and-paper. I got the idea from Umberto Eco’s How to Write a Thesis, a book so brilliant it still remains relevant today, almost 40 years after publication.

An index card is a 3 x 5 inch piece of heavy paper used to record information (often a single idea), first invented by Carl Linnaeus (the botanist who gave us the modern biological naming scheme) about 250 years ago.

Unfortunately, index cards are not locally available. So I had to improvise. I went to Pettah, bought a packet of 200gsm paper (normal photocopy paper thickness is 80 gsm), and had a greeting card shop cut it into 3 x 5’ pieces. I bought a fine felt-tipped pen to write on them (unlike a ballpoint, it forces me to take my time to write neatly). The result:

index-card

Read more...

Down the rabbit hole of ORM hate

29 May 2015

All I wanted to do was to link to the Wikipedia article on ORM (Object-relational mapping) in a post contemplating moving from Sequelize, the Node.js ORM we currently use, to Waterline, a newer and somewhat fancier looking ORM used in the Sails.js framework.

Then Google spat out this as the first search result for “ORM”: ORM Is an Offensive Anti-Pattern – a highly opinionated article that seem to be based almost entirely on the author’s bad experiences with Hibernate. I’ve heard ORM described as the Vietnam of computer science about ten years ago (read Jeff Atwood’s much shorter take on it if you found the original post too wordy), but to see this so high up the search results was a bit jarring.

ORM Is an Offensive Anti-Pattern

Read more...

Read today

28 May 2015

What’s fair?: New theory on income inequality

Excerpts:

Columbia Engineering Professor Venkat Venkatasubramanian has led a study that examines income inequality through a new approach: he proposes that the fairest inequality of income is a lognormal distribution.

“This unified framework of game theory and statistical mechanics, which I call statistical teleodynamics, offers us new insights about both disciplines and answers some long-standing open questions in economics and game theory,”

income distribution

Figure: Global income inequality trends over the years: Blue lines: bottom 90%; green lines: top 10%-1%; red lines: top 1%; black dashed lines: 0% ideal reference. (Original)

Read more...

Jekyll post script

28 May 2015

I copied and adapted this simple script by tlatsas for creating new Jekyll posts. This post was created using this very script.

#!/bin/bash

if [[ -z $1 ]]; then
    echo "A post title is required. Bye.."
    exit 1
fi

EDITOR='focuswriter'
_post=$(echo $1 | tr ' ' '-')
_date=$(date +'%Y-%m-%d')
_datetime=$(date +'%Y-%m-%d %H:%M:%S')
_title="${_date}-${_post}.md"
_cwd=$(pwd)'/_posts'
_post_file="${_cwd}/${_title}"

if [[ -f ${_post_file} ]]; then
    echo "File already exists. Bye.."
    exit 1
fi

cat << EOF >| ${_post_file}
---
layout: post
title: $1
date: $_datetime
---
EOF

echo 'File created successfully.'
echo

${EDITOR} ${_post_file}

echo -n 'Post? y/n : '
read answer
if [[ "${answer}" == 'n' || "${answer}" == 'N' ]]; then
    exit 0
else
    git add .
    git commit -m post
    git push
fi

exit 0