Tuesday, January 3, 2017

Time travelling development--for JS apps

TL;DR To how things should really work, watch this talk by Dan Abramov who created Redux, and the debugger concept.

Long version:
Make a change in your code. See it updated instantly. That's what I want because modern development is an iterative process, with fast iterations.

We've got something like that in JS playgrounds like JSFiddle, CodePen, and so on. But there's still a couple of things that are wrong. Make a change and the app runs again, from the top.  It's pretty quick, and for small bits of code, there may be almost no lag. But as your app scales, the time grows.

You can write a test driver, so that once the app loads, it tests itself, but that's another whole lot of code that you have to write. And even then, reloading takes time, and most of the changes that you make are teeny tiny ones. Even a second or two for a reload is too long.

You can do this in your Dev environment, as well as

And you don't want to test your whole app every time you make a change. Most changes are not going to break the app. They're just little tweaks. What you'd like to do is this: put the app in a certain state. Make your code change. Do some fiddling with the interface. See if it works right. If it doesn't then:

  • Revert to the earlier change
  • Rerun the interface twiddles
  • Repeat until it's perfect
  • Make this the new base, state
  • Repeat forever
And if you run into problems you'd like to go back to your base state with the ability to back up through the twiddles and debug anywhere. Now someone has pretty much done that using mainstream tools.

The key is making your code functional. Take state out of the functions. It's a variation on MVC programming. And it points out a flaw in MVC.

The usual MVC routine is this: you've got a data structure, which is your model. You've got code that takes the Model and renders a View. The view contains UI Control components. When a user manipulates the Controls, the model changes -- either by two-way binding, or by calling functions that are part of the Model, or by directly manipulating the Model data structure. But sometimes the View has its own controlling data structures. So there's a Data Model, and a View Model to pay attention to.

Instead, design code using Model, View, Controller, and Actions. The rules are:

All state is in the Model. Base data state and View state are in different parts of the one and only Model.

Models are POJOs, so they can be serialized and parsed back to their former state.

Actions are Plain Old Javascript Objects (POJOS) emitted by Controllers. 

A part of a Model is updated by calling a model updating function with an Action. There is no other way to update a Model. Model updating functions are called Reducers.

Reducers functions have the following signature: (Oldstate, action) -> newState, the signature used for functions called by Array.reduce They take the prior state as an input parameter and produce a new state. Because of their signature, reducers can be called with an array of Actions, using Array.map. So calling:
arrayOfActions.reduce(reducer, initialState)
Will return the final state, after applying all of the actions. 

Reducers don't update the Model; they replace the old state with a new state, in which the changes have been made according to the Actions. So state objects are immutable.

As a consequence:
  • We can save and restore the application state at any time
  • We can take any state, and apply a set of actions to it, giving the state after the actions
This lets us create a debugger that will do what we want it to do.

The technologies that make this easy to do are React and Redux. React is a framework for view rendering. In ordinary practice, View components can be stateless or stateful. Redux is a framework for managing states for React-based applications so that View components can be stateless.

To see how this works, watch this talk by Dan Abromov who created Redux, and the debugger concept.

Also read the docs for React and Redux, which I am in the process of doing.

No comments:

Post a Comment