“Transmission” in a nutshell
Flux architecture was meant to make the complexities of front end development more manageable. While Flux (and its variants like Redux) seems to have done a great job in eliminating the pitfalls of two-way data binding, I cannot help but wonder if it hasn’t actually made things worse: many developers spend more time trying to figure out glue code (actions, action creators, dispatcher, stores, reducers) rather than writing the code that actually does the work.
Here I propose an alternative to both Flux and MVC. In a way, you may think of it as a hybrid of the two. Consider an architecture with the following three elements:
If you fail to see the difference between MVC and TX, the sample code below might help.
Here I will implement only the “create todo” part of a simple todo app. And in order to demonstrate that the engine has to be completely UI-agnostic, the UI in this example will be a command line interface.
First, let’s look at the TodoEngine. It implements an API as simple functions that complete their jobs and emit events.
The TodoShell (or UI) reacts to user interactions by simply emitting events (the shell itself does nothing). Something else is expected to listen to these events, make the decisions and tell the shell what to do next using its API (e.g. navigate to a different screen, show an error, add an item to a list etc.)
Note that in this example, the API function names are the same as the engine for simplicity— it doesn’t have to be that way. The transmission can map these two APIs any way you want.
Here’s how a transmission layer will connect the engine and the shell. It only contains wiring — no logic, state, or view concerns at all. onShellEvent() listens to shell events and calls engine API in response. onEngineEvent() listens to engine events and calls shell API in response.
Here’s how you’d run the application:
For the full source code:
git clone [email protected]:hliyan/epc-test.gitcd epc-testnpm installnpm install -g jestnpm test # run unit tests
npm start # run the command line apptodo> add hello # how to add a new todo item from the app prompt
I haven’t an example yet, but a React based shell is fairly trivial: simply fire events on onClick, onKey* events on interface elements (e.g. shell.events.TODO_TEXT_ENTER_KEY), and expose an API that ultimately changes component props (e.g. addTodoToList(todo), filterList(‘completed’)). I hope to create a TodoMVC example soon.
I’ve already had seven developers use a more rudimentary version of this architecture on three different front end applications. Each one was more successful (easier and faster to code, less error prone and easier to debug) than previous Redux implementations. For my next project, I plan to use Transmission architecture fully. I will of course report back with observations and more learnings.
Credits: thanks to Pasindu Rumal Perera (@udnisap) for double-checking my work and suggesting improvements.