Category: Pipeline

I’m old and set in my ways.

Today, I had a colleague question my use of a state object. He was just asking questions about its usage and other general questions about the code I wrote and how to refactor it. He wasn’t slamming my code or anything, but it made me remember the times my code has been slammed by someone that thought differently than me about coding.

Like many developers, having other people review your code can be a little hairy. I feel like I am waiting on a judgement to be reached and a sentence to be passed down. I’ve always hated having to hear from the code reviewers that thought nothing of writing a 100+ line method or 800+ line class. Those “just make it work” aficionados that made my life hell when I had to maintain their monsters by bolting more shit on top of shit and praying a new bug isn’t introduced.

Now, I don’t give a hoot what you think about my code unless you can give me a solid argument on why I should change it. Not saying I am a perfect coder, but I know there are a thousand ways to code the same thing. Some ways are better than others, but I’m not changing for change sake to appease your sensibilities. You have to provide proof that my code is so terrible that I have to go in a change it.

For example, I don’t like holding public state in a class that performs logic because you never know who will change the state. I will still have public read/write properties from time to time, but it always feels dirty when I do. So, I pass state through a constructor to readonly properties or through public method parameters. I don’t like having more than four method parameters, so I will create a plain old C# object (POCO) with no logic to hold state that I can pass to methods. I don’t like methods that do more than one thing (with thing being defined by me) and I like expressive sometimes long method names.

After years of learning about patterns, SOLID, DDD, functional programming and more, this is just how I naturally roll now. I don’t even think about it anymore. It just instinctively drives my fingers as I code in some zen state of mind. Does it create complexity, yes. Do I still write bugs, yes. Does it make the world a better place, no. I’d rather deal with the complexity and simple logic bugs than a bug related to some weird and unknown state mutation with error messages two times removed from the root cause of the damn bug.

You can complain about all the small methods I write that are doing one thing exceptionally well. You can roll your eyes while you have to follow a bunch of method calls with long names that explain what they do. I’m not changing the way I think about this anytime soon. So, if you ever have to read my code… suck it up deal with it and run the unit tests as you try to make it better. 🙂

FIXED: Error Building Cordova in Visual Studio

So, I am trying to build an Apache Cordova project in Visual Studio 2015 and it is not playing nice. I see quite a few errors related to npm, so I’m going to blog it out.

Errors

First the errors. Here is a sample of them:

FindPackagesById: System.Console; File: RUNMDAINSTALL 

Error ENOENT, no such file or directory ‘C:\Users{name}\AppData\Roaming\npm\node_modules\vs-tac\node_modules\edge\src\CoreCLREmbedding\project.lock.json’; File: RUNMDAINSTALL 

BLD401 Error : BLD00401 : Could not find module ‘C:\Users{name}\AppData\Roaming\npm\node_modules\vs-tac\app.js’. Please Go to Tools –> Options –> Tools for Apache Cordova –> Cordova Tools –> Clear Cordova Cache and try building again. 

Solution

There is no way that I can say what the real solution is because it is dependent on versions of node, npm and VS Cordova Tools, but if you have a vs-tac issue, try:

  1. Clearing your Cordova Cache:
    in Visual Studio Go to Tools > Options > Tools for Apache Cordova > Cordova Tools > Clear Cordova Cache
  2. Copy vs-tac from your VS install to your profile:
    C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\ApacheCordovaTools\Packages\vs-tac to C:\Users\{name}\AppData\Roaming\npm\node_modules
  3. Manually install any missing node dependencies globally:
    >npm install {dependency name} -g

My Journey to Solution

First I tried the fix in the last error above: Options –> Tools for Apache Cordova –> Cordova Tools –> Clear Cordova Cache and try building again. This didn’t work, but I learned where the Cordova config is so that’s a plus.

Next I tried to manually install Cordova from npm and got this lovely error:

npm ERR! Failed to parse json
npm ERR! No data, empty input at 1:1
npm ERR!
npm ERR! ^
npm ERR! File: C:\Users\cbryant\AppData\Roaming\npm-cache\xtend\4.0.1\package\package.json
npm ERR! Failed to parse package.json data.
npm ERR! package.json must be actual JSON, not just JavaScript.

So, I went down the rabbit hole and focused on fixing this as it may be part of my original problem.

npm cache clean
npm install cordova -g

This worked, I was able to install Cordova manually, but had no effect on my original problem and this Yak still has a lot of hair to shave.

So the issue is linked to some npm package named vs-tac. A little searching and I discovered that it may already be installed here: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\ApacheCordovaTools\Packages\vs-tac.

Let’s try to install it to my profile to see if that fixes the issue.

npm install “C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\ApacheCordovaTools\packages\vs-tac” -g

OK, I’m seeing some of the same errors that I see in Visual Studio. I discover that some of the errors are because of a bad Nuget source, so I remove the source and land on this error:

npm ERR! Failed at the edge@5.0.0 install script ‘node tools/install.js’.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the edge package,
npm ERR! not with npm itself.

How do you check the latest version of node.js and npm? I asked Google the same questions:

node -v
npm -v

I am running node 5 and the current stable is 4, not sure if that is an issue. Going to run the latest msi for v5 to see if it does something. By the way you can find all of the node installers here: https://nodejs.org/dist/.

Upgrading npm was a little different. I have npm installed in my node install, C:\Program Files\nodejs\npm.cmd. To upgrade I found this command

npm install npm -g

This installs the latest npm to my profile, but I assume running npm defaults to the one in the node install (based on a couple posts I read). So, I deleted the one in the node install and everything is upgraded and working (By the way, I had to restart my administrator command prompt to get npm to work at the new location), but I still get the last error above (still shaving this yak).

So, I have to read logs :(, C:\WINDOWS\system32\npm-debug.log. After a painful read, I give up on the command line and manually copy vs-tac from C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\ApacheCordovaTools\Packages\vs-tac to C:\Users{name}\AppData\Roaming\npm\node_modules. When I build again all of the errors are gone except one:

BLD401 Error : BLD00401 : Could not find module ‘elementtree’. Please Go to Tools –> Options –> Tools for Apache Cordova –> Cordova Tools –> Clear Cordova Cache and try building again. StationHouse.Mobile

I clear the Cordova Cache and it deletes the vs-tac in my profile. I add vs-tac back and build again with the same error. I go to check the package.json in the vs-tac folder and notice that node_modules doesn’t exists so I run npm install inside this directory to install the packages, but edge still won’t install.

I manually install edge:

npm install edge@5.0.0 -g

When I rebuild it succeeds, that yak has a nice crew cut.

 

 

 

KISS Your Big Data UI

It’s been so hard to blog lately. Mostly because I don’t have time to edit my posts. I guess if I wait until I have time to wordsmith better posts I’ll never post, so here is one that has been sitting on the shelf in all of its unedited glory.

What Qualifies A Developer To Talk About UI Design

I’m not qualified, I am not a designer. I haven’t done a lot of posts on the subject of UI design, but with the big push to big data, real-time streaming analytics, and IoT, I thought that I’d put a little thought into things that I would think about when designing a UI for them.

I started my tech career designing websites and desktop applications for a few years. Although my customers were happy with my UI designs, it’s not my thing and I don’t think I am good at it. Yet, I have been on many application teams and have had to work with many awesome designers. I believe that I can speak on UI design considerations from my 16 years of doing this. What I have to say is not gospel. I haven’t searched this stuff out on Bing like I do with engineering problems. Many UI and usability guru’s will probably crush me if they read this, but I’m not totally clueless when it comes to UI’s.

A Dashboard for Big Data

When dealing with designing an administrator’s dashboard for IoT device sensor data or maybe any big data application you should probably focus on making the right exceptional conditions highly visible and showing actionable data trends with the ability to drill down for more information and take necessary actions. The most important thing is to alert users of potential problems and anomalies that may indicate pending problems while providing some facility for taking action to investigate and mitigate problems. Just as important is being able to identify when something is going well because you want to learn from the successes to possibly apply the knowledge to other areas.

The UI should assist the user in being proactive in addressing problems. This is true if you have one device sending sensor data or a fleet of them. Granted there are differences in design consideration when you start scaling to 100s or 1000s of devices, but depending on the goal of the device, the basic premise is you want to make certain conditions identified by sensors up front and in your face.

KISS Your UI

When you have 100s of messages flowing from sensors compounded by multiple devices, a pageable grid of a hundred recent sensor messages on the first screen of the UI is useless, unless you are the type that enjoys trying to spot changes while scrolling the Matrix. The dashboard should lead you to taking action when problems exist, help you learn from successes, and give you peace of mind that everything is OK. The UI should help you identify potential areas to make improvements by uncovering weaknesses. This should be done without all of the noise from the mountain of data being held by the system.

If you could only show one thing on the UI what would it be. Maybe an alert box showing the number of critical exceptions triggered with a link to view more information? Start with that one thing and expand on it to provide the user with what they need. Big data UI is not a CRUD or basic application UI. It more closely related with what one might do for a reporting engine UI, but even that is a stretch. I am sure there are awesome blogs and books out there that speak on this subject, but many of the UIs I have been seeing were designed by people that didn’t get a subscription or something.

Keep It Simple Stupid (KISS) is as much a design principle as it is in software engineering. Stop making people work to understand thousands of data points when it should be the job of the UI designer to simplify it for them.

Example

Say you have a storage company. You have hundreds of garages and you want to deploy sensors to each garage and allow your customers to monitor them. The sensor will give you data on the door being open or closed, temperature, and relative humidity in the unit. The devices send messages every 5 minutes, 7,200 messages a day.

Your customers can opt in to SMS and email alerts on each data point. Some will only want open/close alerts. Some may have items that are sensitive to heat and humidity and they will want alerts when temperature or humidity cross some threshold.

Your customers also get access to a website that allows them to modify alerts and view a dashboard that allows them to investigate and query all of the sensor data. What good would it be to have a grid on the dashboard showing sensor data streaming into the UI every 5 minutes, 7,200 times a day. Why burden them with even having to see the data. Most customers will never have a breach. Temp and humidity sensitive customers will probably have an environment controlled unit that rarely triggers and alert. What does streaming data on the initial dashboard screen give them… nothing.

The only thing most of the customers want to know is has someone opened my unit or if the temp is fluctuating. The customer wants us to simplify all of that data into a simple digestible UI that addresses their concerns and helps them cure any pain they may experience when an alert is triggered.

There may be users that need to dig into the data to investigate, but normal daily usage is focused more on alerts and trends. Seeing all of the data is not the main concern and the data is only available if they click a link to dig into it. The UI is kept clean, not overwhelming, and focused on the needs of the majority of customers.

This is fictional and if no one is doing it, I probably just gave away a new app idea. This is the reason that IoT is hot, its wide open for dreamers. The gist of the example is there is so much data to contend with on these types of projects you have to hide it and simplify the UI so that you aren’t overwhelming the user.

Consumer Apps Are Not the Only Game In Town

Additionally, you have to take into account whether the UI is for consumers or businesses. Making things pretty for consumers can help to differentiate an app in the consumer market, but the time to make things pretty for B2B or enterprise is better served on improving usability and the feature set. I am not saying that businesses don’t care about aesthetics, but unless they are reselling your UI to consumers it’s usually not the most important thing. For both audiences usability is very important, but usability doesn’t mean using the latest UI tricks, fancy graphics, fussing over fonts and colors just for the sake of having them. Everything should be strategically implemented to help usability.

This is especially true for large enterprises. I have seen many very successful and useful apps in the enterprise that were nothing more than a set of simple colored boxes with links to take certain actions and drill down into more information. So, you not only have to take into account the amount of data being managed in the UI, but the user doing the managing. Know your audience and build the UI to their needs. Leave out all the gradients and curves and UI tricks until you have a functional UI that serves the core needs of the business and leave polish for later iterations. Focus first on how to reduce the mountain of data into bite sized actionable chunks.

Conclusion

So, Keep It Simple Stupid! Hide the data, show alerts and trends, allow drill down into the data for investigation, provide a way to take action, leave polish for later iterations.

How do you do to spell relief?

How do you handle Sev 1 critical outages?

Stay calm

Sev 1 outages are stressful. When production is down and customers are affected and everyone is looking at your team for an answer, first and foremost stay calm… breath. This is easier said than done when you are affecting millions of dollars per hour in transactions (which is a thing in large scale payment systems, not fun), but regardless of the impact of the outage, if you loose your cool, the solution can be sitting right in front of your face and you won’t see it. Shit happens, there will always be bugs, sites will always go down at some point, accept it, find the solution and focus on not letting the same shit happen twice.

Don’t focus on blame

Establishing who caused the issue is not important? Knowing who may have been involved in the changes that led up to an issue and made changes after the issue is important to understand. Even if there may have only been one person involved, you can’t assume that they are the cause and it does no good to blame anyone when production is down. Focus on the solution.

Create time line of events

You should document all relevant changes that led up to the outage and all changes that occurred after the outage. This not only helps to discover possible causes it provides documentation that can be used during root cause analysis and investigations during similar outages.

The time line can be kept on an internal team wiki so the team has visibility and can add to it as necessary. During an outage, someone should be assigned to record all of the facts in the time line. Without facts your poking at the problem in the dark.

Never theorize before you have data. Invariably, you end up twisting facts to suit theories, instead of theories to suit facts.
Sherlock Holmes to Watson (Movie – Sherlock Holmes 2009)

Investigate logs

I can’t tell you how many times that checking the logs first would have saved a lot of time as opposed to just poking around looking for file changes, config changes… everything else, but simply looking at the logs. The first step in investigating the issue should be looking at all of the relevant logs: event logs, custom application logs…

Communication is key

Keep a bridge line open with team

Keeping a bridge line open, even if there is nothing to discuss, keeps a real-time line of communication open and ready when someone has questions, ideas, and possible solutions.

Send regular status updates to team and stakeholders

Sending a message to announce the issue and what is known right now is good form. It lets everyone know that you are on top of the issue and working hard to solve it. If you haven’t found a resolution in a certain amount of time, sending another update explaining what has been done and any new findings lets everyone know that although you haven’t found the issue, you are still working hard on it. It may be a good idea to even post the status updates to a blog or Twitter, syndicate the updates to as many channels as you can, especially if you have a large application with many users.

Staying proactive with communication is much better than constantly having to field random calls and emails looking for information you should be readily sharing. Keep communications open and don’t try to hide, spin, or lie about the mistake.

No one makes any changes without discussing the change

While everyone is trying to solve the issue, no one should be making changes in production, even if the fix is blatantly obvious. A Sev 1 is serious and everything changed to fix it should be discussed with the team first so it can be documented and controls put in place to prevent it in the future.

If the team agrees on the change then the change should be documented on the timeline and a notification should be sent when the change is starting and when the change is finished. The change discussion and notifications can be simply talking it out over the bridge line or an IM or email. The point is don’t allow the change to get worse or be repeated by making undocumented changes that the team can’t learn from.

 

Conclusion

These are just some tips that I have learned over the years. I have seen many more sound practices, but the gist is:

  • Stay calm
  • Document changes to production
  • Work as a team
  • Learn from failure

Stand Up, Sit Down, Just Collaborate

I haven’t blogged in a while. I started a new job and I’ve just been busy getting acquainted. Well at the new gig we have been exploring ways to improve as a team. Stand ups have been brought up a few times.

I Hate Stand Ups

In my experience stand ups have been over rated status meetings. Maybe that’s because I haven’t been on a team doing scrum correctly or maybe standups are dumb, I’m not sure. I have done standups for years on multiple teams and there was waste in every one of them. There were some standups that were too big and ended up with a bunch of people with blank stares because most of the standup was irrelevant to them. There were some that were too small and redundant because the team collaborated closely throughout the day, so nothing new in standup. There were some that were unwieldly and not focus on standard scrum standup reporting and just a big waste of time. In most, there have rarely been instances where blocks were unblocked or time not wasted.

In all of these stand ups I had the feeling that there must be a better way than doing a thing in a religious fashion just because some abstract process that the community follows like sheep says so.

I envision a life without standups with a process that provides easy ongoing reporting of project status and impediments. Discussing project status is important for determining if a project is on schedule and if the financial goals of the project will be met. Discussing impediments are important because resolving issues that are blocking tasks will help prevent the project schedule from being in jeopardy and helps reduce frustration.

There is usually someone that is responsible for project status reporting. This person can make daily rounds and collaborate with the team on the collection of regular status and to work through some of the project impediments. I say some because some impediments are technical and require another team member to solve. Anyway, all of this could be done in a status meeting, but status meetings whether they are sit down or stand up have a tendency to turnout just like my experience with standups. One-on-one collaboration on status whether it is face-to-face, IM, or phone may be extra work, but I believe it provides more value in terms of time and effectiveness for the team. If you want to keep it srum’ish, the status walk through can be time boxed to a certain amount of time per person.

We addressed project impediments, but what about technical ones. We are a team, why can’t we just collaborate? Most likely you have an idea of who to ask for technical help and if you don’t you know how to reach out to your team to find out who can help. Go talk to someone. If you can’t ask your teammates for help for whatever reason, your team has a problem. I have been on teams with people who were closed to answering questions, but this is a new agile day. If you don’t want to help the team, you need to go solo. You don’t deserve to benefit from the fruits of the team’s labor if you don’t want to contribute to the team. If you are scared to ask for help, get over it. When you are wasting time on something that can be solved by just asking someone on the team is a disservice to your team. Taking a little time to discuss a problem and get pointed in a new direction is not an indictment of your skills. It’s a reason for you to collaborate and become a more cohesive team. This is not to say that you shouldn’t put in your due diligence or pound the same person with multiple questions day in day out. Become a nuisance and you may get voted off the island.

I guess my point is, you can be agile without scrum, you can do scrum without standups. If a process isn’t working, improve it.

OK, end rant… for now.

Part 7: Get Up and Running with #React and #TypeScript

The “Get Up and Running with React and TypeScript” series is made up of posts from chapters in my book “Hello React and TypeScript“. If you have questions, comments or corrections, please reach out to me in the comments or on Twitter @charleslbryant.

You can view the posts in this series on the Hello React and TypeScript category page.

Component Composition

https://charleslbryant.gitbooks.io/hello-react-and-typescript/content/Samples/ComponentComposition.html

This sample gives a basic example of refactoring the Hello World application by composing the UI with modular components.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.7

src/helloworld.tsx

/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';
import HelloForm from 'helloform';
import HelloContent from 'hellocontent';

export default class HelloWorld extends React.Component<any, any> {
    constructor(props: any){
        super(props);
        this.state = { name: this.props.defaultName };
        this.handleChange = this.handleChange.bind(this)
    }

    public handleChange(event: any) : void {

        this.setState({ name: event.target.value });
    }

    public render() {
        return (
            <div>
                <HelloForm 
                    name = { this.state.name }
                    handleChange = { this.handleChange } 
                />
                <HelloContent 
                    name = { this.state.name }
                />
            </div>
        );
    }
}

The HelloWorld component is updated to compose the same UI as the previous example using two modular components, HelloForm and HelloContent.


import * as React from 'react';
import HelloForm from 'helloform';
import HelloContent from 'hellocontent';

To compose with components the components you want to compose have to be in scope. To do this we import the components. HelloForm and HelloContent are imported by using the import statement with the from value being the name of the component.


public render() {
    return (
        <div>
            <HelloForm 
                name = { this.state.name }
                handleChange = { this.handleChange } 
            />
            <HelloContent 
                name = { this.state.name }
            />
        </div>
    );
}

The actual composition occurs in the render method. We add the HelloForm and HelloContentcomponents. Notice that the name of the components start with uppercase to differentiate them from HTML elements. Each of the components accept some properties and we pass them with a syntax that is similar to defining HTML attributes.


By composing UIs in this manner we move from an imperative style of building UIs to a declarative one. Instead of defining every element and attribute we want to use in the UI we delegate the definition to a modular reusable component.

Since the modular components are reusable we can compose multiple UIs with them. We can compose with components developed by other teams. We get to focus on the unique aspects of our domain and delegate other lower level concerns to modular components.

src/helloform.tsx

/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloForm extends React.Component<any, any> {
    constructor(props: any){
        super(props);
    }

    public render() {
        return (
            <div>
                <input 
                    value={ this.props.name }
                    onChange={ e => this.props.handleChange(e) }
                />
            </div>
        );
    }
}

Here we have a new component responsible for the collecting user input for our tiny application. By now this code should be familiar. We just moved the input element from the HelloWorld component and encapsulated it in this new component.

For this simple example we are storing all of our components in one folder. As your application grows you may want to use a folder structure that makes the number of component files more manageable. When you are at the point of doing this you will have to address the reference path for the TypeScript typings. It will become a maintenance issue having to keep the path in sync as you move components and build new folder structures, but we won’t go into that just yet.

src/hellocontent.tsx

/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloContent extends React.Component<any, any> {
    constructor(props: any){
        super(props);
    }

    public render() {
        return (
            <div>
                Hello { this.props.name }!
            </div>
        );
    }
}

This is a component responsible for displaying the hello message. Again, this component is a result of encapsulating this section of the DOM out of the HelloWorld component.

Stateless Components

One interesting observation about these components is that they are stateless. They don’t hold any state and they rely on a parent component to pass props to it in order to do its work. This includes event handlers and data as you can see in the sample code.

When possible using stateless components are preferred in React. They help to improve performance because they lessen the amount of processing that React has to do with the component.

Part 6: Get Up and Running with #React and #TypeScript

The “Get Up and Running with React and TypeScript” series is made up of posts from chapters in my book “Hello React and TypeScript“. If you have questions, comments or corrections, please reach out to me in the comments or on Twitter @charleslbryant.

You can view the posts in this series on the Hello React and TypeScript category page.

Accept User Input

This sample gives an basic example of accepting user input.

Source Code

https://github.com/charleslbryant/hello-react-and-typescript/releases/tag/0.0.6

src/helloworld.tsx

/// <reference path="../typings/tsd.d.ts" />

import * as React from 'react';

export default class HelloWorld extends React.Component<any, any> {
    constructor(props: any){
        super(props);
        this.state = { name: this.props.defaultName };
    }

    public handleOnChange(event: any) : void {
        this.setState({ name: event.target.value });
    }

    public render() {
        return (
            <div>
                <div>
                    <input 
                        onChange={ e => this.handleOnChange(e) }
                    />
                </div>
                <div>
                    Hello { this.state.name }!
                </div>
            </div>
        );
    }
}

The significant changes here are we removed the button and handleOnClick method. We also added a text box and a handleOnChange method to handle changes as a user adds input to the text box.


public handleOnChange(event: any) : void {
    this.setState({ name: event.target.value });
}

This is a new method to handle the onChange event. In the method we are calling this.setState and updating the value of name in this.state to the value of the target element passed in the event.


public render() {
    return (
        <div>
            <div>
                <input 
                    onChange={ e => this.handleOnChange(e) }
                />
            </div>
            <div>
                Hello { this.state.name }!
            </div>
        </div>
    );
}

Here we added an input element and set its default value to this.props.name. We also bound the text box’s onChange event to handleOnChange method.


With these changes we have implemented a unidirectional data flow.

  1. When the user enters something in the text box it triggers the onChange event.
  2. The onChange event is handled by the handleOnChange method.
  3. The handleOnChange method updates the value of name in this.state and triggers a re-render of the component with this.setState.
  4. this.setState ends in a call to the render method that updates the name in our “Hello” message.

State is only changes as the result of an event. The Hello message is no bound to an external model state and can only be updated as a result of an event being triggered by user input. This is different than two way binding or bi-directional data flow where changes in a model can also update the state of a view.

Unidirectional Data Flow (UDF)

event > event handler > state > render

Components are representations of the state of a view over time. As events are triggered over time they update state and re-render the component with the new state. The flow can be seen as a stream of events that flow in one direction that eventually update component state causing a component to re-render. If you know about CQRS, event streaming, or stream processing, there are similar concepts in each. UDF is a redundant theme in learning React, hence a redundant theme in this book.

The sample is a simple naive example because we aren’t dealing with external or persisted data. The scope of the example makes it a little hard to understand UDF. In the example we don’t have to worry about updating an external store.

If you are having trouble understanding UDF, when you learn about Flux it will makes more sense. The Flux architecture helps you visualize data flow in a circular one way round trip. Even though it may be hard to see UDF within the context of a single component the same event flow is used to accomplish UDFin React whether within a single component, a Flux architecture, or using Relay (another Facebook library). When you get into Flux or other data flow patterns or libraries, UDF will be expanded to add additional concepts into the data flow.

UDF vs Bi-directional Data Flow

The important thing to notice about UDF is that we aren’t attempting to create a complex bi-directional view binding with some external model. We are binding to the state modeled within a component with no dependency or complex mapping to some external data model. The component is responsible for expressing its own state, updating its state, passing properties to its child components, and re-rendering itself and children when state changes as the result of some event.

If we were to use a bi-directional binding to an external model, we would not know why state is being updated. Any number of views could have the same binding to the same model. With bi-directional binding a change to a view or model could cause updates to multiple models or views and it becomes hard to understand the data flow, especially when you are trying to solve a Sev1 incident.

If you’d like to know more about UDF, there is a lot about it online that can be found with a simple search. Actually, the original MVC pattern is an example of UDF. It was distorted when it moved to web clients. If you’d like to dig into the theory behind React and UDF, you can research Functional Reactive Programming – https://en.wikipedia.org/wiki/Reactive_programming.