Category Archives: react

Layering in new behavior with React

I’ve talked in the past how I like the approach React leads me to when it comes to building apps. How does such grandiose talk play out when it’s time to add a new, unexpected feature? Let’s check it out. I’ve been building an installation app for Spinnaker, and one of our top notch developer advocates gave it a spin.

Results? Not good. Too many presumptions were built into the UI meaning he had no clue where to go. Message to me? Fix the flow so it’s obvious what must be done and what’s optional.

So I started coding in a feature to flag certain fields REQUIRED and not allow the user to reach the installation screen without filling them out. Sounds easy enough in concept. But how do you do that?

With React, what we’re describing is an enhancement to the state model. Essentially, keep filling out fields, but earmark certain fields as required, and adjust the layout of things to show that, while barring other aspects of the interface in the event those same fields aren’t populated.

So I started with a little bit of code to gather a list of these so-called required fields, and it looked like this:

If you have done any React programming, assigning something via this.state[…] = foo should set off bells in your head. You always, always, ALWAYS used this.setState(…). So what’s up?

Rules are rules until they aren’t. This is a situation that defies the concept. I don’t WANT to set the state such that it triggers a ripple through the DOM. Instead, this code happens right after the initial state model is initialized. And I’m setting it using values populated in the previous line, because you can’t initialize required, pointing at this.state.api in the same call the initializes this.state.api itself!

With this list of required fields setup, we can start marking up the fields on the UI to alert the user. I have a handful of React components that encapsulate different HTML inputs. One of them is dedicate to plain old text inputs. Using the newly minted required list, I can adjust the rendering like this:

Notice the little clause where it checks this.props.settings.requires.includes(this.props.name)? That is a JavaScript ternary operation that if true, returns the label with extra, highlighted text. Otherwise, just render the same label as always.

By applying this same tactic to the other React components I have for rendering each selection on the UI, I don’t have to go to each component and slap on some new property. Instead, the designation for what’s required and what’s not it kept up top in the state model, making it easier to maintain and reason about.

At the top of the screen is a tab the user clicks on to actually install things and track their progress. To ensure no one clicks on that until all required fields are populated, I updated that tab like this:

A little function that detects whether or not all required fields have been filled out is checked, and if so, renders the HTML LI with its onClick property filled out with the handler. If NOT, then it renders the same component, but NO SUCH onClick property is present, meaning it just won’t respond.

This is the nature of React. Instead of dynamically adjusting the DOM model, you declare variant layouts based on the state of the model. This keeps pushing you to put all such changes up into the model, and writing ancillary functions to check the state. In this case, let’s peek at requiredFieldsFilledOut:

This tiny function checks this.state.required, counts how many are “truthy”, and if the count matches the size of this.state.required itself, we’re good to go.

In case you didn’t know it, React encourages you to keep moving state-based functions up, closer to the state model itself. It’s super simple to pass along a handle to the function to lower level components, so they can still be invoked at lower levels. But anytime one component is trying to invoke another one in a separate part of the hierarchy, that’s a React-smell hinting that the functions should be higher up, where they can meet. And that results can trickle down to lower level components.

I encountered such a function stuffed down below in a lower level component. The need to trigger it sooner based on a change in the state had me move it up there. Now, when the Installation tab is clicked, that function is run, instead of waiting for the user to click some button down below.

Suffice it to say, I rehabbed the UI quite nicely. The thing is, with React it’s not hard to effect such change in a couple days, compared to the days or weeks of effort combined with testing it might have taken with classic manipulated-the-DOM apps, where you have to hunt down gobs of wired event handlers and find every little nuanced operation you coded to make things operate correctly.

The beauty of coding frontends with React

This industry can be quite brutal. Tools come and go. Programming styles invented fifty years ago suddenly become relevant. But I really enjoy when a certain toolkit nicely presents itself over and over as the way to go. I’m talking about React. Every wonder what it is that has made coding frontends with React so dang popular? Let’s take a peek.

What’s so good about React?

React innovates frontend development by moving the focus off of cobbling together DOM elements. Instead, it shifts things toward laying out a declarative UI and driving everything by a consolidated state model. Update the state and the layout changes automatically.

In traditional JavaScript toolkits, you find yourself writing DOM finagling code bits inside event handlers strewn throughout the code base. (jQuery, I’m looking at you!) Managing, organizing, and maintaining order of this code is a chore that isn’t hard to fail. It’s easy to NOT cleanup properly and let your app leak.

Get on with the example already!

With React, you lay out a series of HTML elements inside the code (and using ES6 makes your eyes stop bleeding!) based on properties and state.

FYI: Properties are read only attributes, State are updateable attributes. In this component, there are NO event handlers. Everything shown is passed through the constructor call and accessed via this.props.

Some people balk at how React mixes HTML with JavaScript in the same file. Frankly, I find keeping things small and cohesive like this as the right level of mixture

It’s possible to have optional components, and they can be based on the centralized state model. Flip a toggle or trigger off some other thing (RESTful payload?) and see components appear/disappear. (NOTE: React smoothly updates the DOM for you.)

Check out the fragment below:

Toward the bottom, orgsAndSpacesLoading is used as a stateful flag to indicate some data is loading. Using JavaScript’s ternary boolean check, it’s easy to display a Spinner. When the code fetching the data completed, it merely needs to update the state of this flag to false, and React will redraw the UI to show the <span> with two dropdowns.

When piecing together event handlers and DOM elements by hand puts you in this mindset of updating the screen you’re looking at. You start to think about hunting down elements with selectors, changing attributes, and monkeying around with low level constructs.

When working with React, you update the state and imagine React redrawing everything for you. The UI is redrawn constantly to catch up to the new state. Everything is about the state, meaning it’s best to invest effort designing the right state model. This pulls your focus up a distinct level, letting you think more about the big picture.

The state must flow

Another neat characteristic you start doing is pushing bits of state down into lower level components as read-only properties. You also push down functions as invocable properties. You may start with functions in the lower level components, but many of them work their way back to manipulating the state. And often the state works best when pulled toward the top. Hence, functions tend to move up, making lower level components easier driven by properties.

This component is a reusable HTML checkbox with a label. You feed it the name of a state attribute and it allows flipping the state attribute on or off. Changes are invoked by the passed in property function, handleChange. This function is actually passed into a lot of various components in this application. You can see how this component is invoked below:

  • The label text is provided – “OAuth?”
  • The name is connected to a property known as settings.oauthEnabled.
  • The function to respond to clicks is this.handleChange.
  • The raw state is passed down as a bit of a free for all.

The point is, nice little components are easy to put together. Bits of state and needed functions are easy to hand off. And we don’t waste frivolous time with building the DOM and thinking about triggering an update in one part of the UI from some other remote corner of the UI.

We simply update the relevant bits of state and let the system redraw itself as needed. Once you get warmed up to this style of building frontends, it’s hard to put it down.

Happy coding!