Exploring React Hooks – 1

by Bob MacNeal, 3 Mar 2019

React, the JavaScript library for building UI components, now supports Hooks.

Hooks, from the Facebook engineering team, resolve a variety of issues and goofy workarounds in the React space (e.g., life-cycle methods, connecting to an application store, and passing stateful logic between components, to name a few).

I embarked on a prototyping exercise to determine how I might best use a few of the built-in hooks, like useState, useEffect, and useRef, in functional components.

Once comfortable with a few of the built-ins, I made a custom hook called useAxiosGetItems. I plan to re-use this hook when I need to wire up GET requests in service-level functions. Indeed I use a slightly modified version of it in the sequel to this post Exploring React Hooks – 2.

The first prototype is called simple-hooksMaterial-UI React components and icons are used for design and functional simplicity.

The simple-hooks application demonstrates how I used hooks to back an interface consisting of four tabs meant to trigger the display of the following item lists:

Todos, Posts, Photos, and Users.

Screen Shot 2019-03-02 at 4.15.41 PM.png

The item lists are fetched from the JSONPlaceholder API.

JSONPlaceholder, the self-proclaimed “Fake Online REST API for Testing and Prototyping”, is a low-resistance API that proved quite helpful in my prototyping to explore React hooks.

Code

The main container in the simple-hooks prototype is the functional component Resource that includes navigational tabs and an ItemList component to display the item lists of the selected resource.

useState

Note the use of useState (below). The useState invocations store the state of which UI tab was clicked (i.e., which resource type the user selected). The const initializes the default state to display TODOs. The second const initializes the default display fields for TODOs. The function handleSwitchTab responds to tab click events by updating the resource type and resource fields.

Screen Shot 2019-03-02 at 4.35.53 PM

resource.js component

The syntax of useState is:
const [propertyName, setPropertyName] = useState(initial condition)

Custom Hook

The custom hook I created uses the useEffect and useState hooks. The motivation behind the custom hook is to provide a generalized approach to making GET requests using the axios HTTP request library.

Screen Shot 2019-03-02 at 4.44.03 PM

useAxiosGetItems is passed a URL. In this case, the URL points to various resources available in the JSONPlaceholder API.

The function makes an asynchronous request. It returns three entities at different times:

  • loading – A boolean that is true until the HTTP request resolves, then changes to false. This loading variable allows for a progress indicator to be temporarily displayed in the UI while the request in in progress.
  • listItems – When the request for the resource items resolves, an array of the requested resource (i.e., ToDos, Posts, Photos, or Users) is populated and returned with loading toggle to false.
  • error – Should an error occur, an object including an HTTP return code and a descriptive message is sent back for display in the UI.

Conclusion

React hooks negate the need for confusing life-cycle methods and enable simple state management in functional components. They also reduce some of the boilerplate required by stateful class components.

Code for this prototype is available in the simple-hooks git repository.

The second prototype I made exploring React hooks is a search application called simple-hooks-search that forms the basis of Exploring React Hooks – 2.

Jump to Exploring React Hooks – 2.

Exploring React Hooks – 2

by Bob MacNeal, 3 Mar 2019

React, the JavaScript library for building UI components, now supports Hooks. In the previous post, Exploring React Hooks – 1, I described an exercise to determine how to best use React hooks in the context of building a prototype called simple-hooks.

In this sequel, I demonstrate how I used React hooks in a second prototype with different requirements, namely a search application called simple-hooks-search.

Like simple-hooks, the search application simple-hooks-search uses Material-UI React components and icons for design and functional simplicity.

React hooks were used to back a simple search application UI (below) with the following elements:

  • input for search terms;
  • an X button to clear the search;
  • a button to submit a search; and
  • a search results list.

Screen Shot 2019-03-03 at 2.55.34 PM.png

Code

The main container in the simple-hooks-search prototype is the functional component Search. This container component includes a component for the form called SearchForm and a component for the results called SearchResults.

In Search (below), useState stores the search term. Setting the search term causes a re-render.

The syntax of useState is:
const [propertyName, setPropertyName] = useState(initial state)

Screen Shot 2019-03-03 at 3.21.51 PM.png

Search.js component

SearchForm

The SearchForm component has a handleSearch function to process search term submissions and a handleClearSearchTerm function to clear the form. Note that handleClearSearchTerm also uses a useRef hook.

Screen Shot 2019-03-03 at 3.36.42 PM.png

SearchForm.js component

The useRef hook (above) is used to set focus on the text input upon clearing the search term.

SearchResults

When a search term is submitted from the SearchForm component, results are fetched from the Hacker News search API for display in the SearchResults component. The salient features of the SearchResults component are:

  1. It receives a search term as a prop from its parent component Search;
  2. It invokes a service layer function called searchHackerNews(searchTerm) to fetch results;
  3. It displays a CircularProgress loading indicator while the request resolves; and
  4. Finally, once the server request resolves, it loops through the listItems adorning them with markup for display. Also note that any error would be displayed (e.g., should the API request fail).
Screen Shot 2019-03-03 at 3.48.36 PM.png

SearchResults.js component

The function searchHackerNews uses a custom hook called useAxiosGetItems. The custom hook takes a URL and the name of the results array in the response from the server as parameters.

Screen Shot 2019-03-03 at 3.54.40 PM.png

searchService.js

Custom Hook

The custom hook useAxiosGetItems has been slightly repurposed (from that used in Part 1) to accommodate the fact that the Hacker News search API returns an array called hits within a response object. The hits array contains the search results we want to display.

Line #14 calls below calls setListItems on response.data[itemListName] where itemListName equals “hits”.

Screen Shot 2019-03-03 at 3.59.59 PM.png

useAxiosGetItems.js

The custom hook uses the useEffect and useState hooks. It returns search results in listItems, a loading boolean for a progress indicator, and any errors that occur during the request (line #25 above).

An asynchronous request is made that returns the following entities (at different times):

  • loading – A boolean that is true until the request resolves, then changes to false. This loading variable allows for a progress indicator to be temporarily displayed in the UI while the request in in progress.
  • listItems – When the request for the resource items resolves, an array of the search results is plucked from the hits array and returned with loading toggle to false.
  • error – Should an error occur, an object including an HTTP return code and a descriptive message is sent back for display in the UI.

Conclusion

With the simple-hooks-search prototype, I once again confirmed that React hooks negate the need for life-cycle methods and enable simple state management in functional components. As with the simple-hooks prototype, hooks also reduce some of the boilerplate inherent in stateful class components.

Code for this prototype is available in the simple-hooks-search git repository.

Note that the first prototype I made simple-hooks, forming the basis of Exploring React Hooks – 1, has similarities but subtle differences to the simple-hooks-search prototype.

Jump back to Exploring React Hooks – 1.

The Big Wave Operating System

I surfed in my teens on tame East Coast waves. The draw to surf and to all aspects of water waves has never left me.

I seek and study waves in lakes, rivers, oceans, storm sewers, and boiling hot springs. And like a kid with a shoe box full of treasures, I have mentally cataloged all of the famous surf breaks from the chilly shores of Lake Superior getting pounded by an October gale to Bali the mystical Island of Temples with its thousand surfing waves.

Mavericks in a legendary Northern California wave near Half Moon Bay that breaks a half-mile out to sea and gets downright perilous to surfers when the winter swells get juicy.

Mavericks is also the name given to Apple’s new operating system upgrade.

Mavericks is not so much the inspiration for a Beach Boys song as it is a symbol of Melvillian existential struggle.
― Stewart Sinclair

As an late Apple products convert, Mavericks strikes me as an appeal to the existential extremes of the extreme sports universe and a curious marketing decision. As a wave Mavericks is one of the ultimate big wave machismo rides on the globe — a death defying free fall down a Matterhorn of water chased by an avalanche of roiling whitewater.

As for Mavericks the OSX upgrade, I haven’t downloaded it because I rely on a MacBook Pro to ply my trade. I am patiently waiting for my smarter teammates to resolve any compatibility kinks with Chrome Driver that might confound our integration tests and potentially munge other development artifacts so I don’t end up dead in the water.


REFERENCES

Not What, But Who

I’ve been moving from project to project for quite some time now. What I’ve realized is that for most professional gigs, it’s not what you’re doing that’s important as much as who you’re doing it with.

I recall a time when my teammates called me Bobby Tables for an entire 2-week iteration. Bobby Tables is developer humor.

Like many of the teams I have been fortunate to work with, everyone was productive but more importantly, our days were humor-filled.

So whenever I piss and moan about this technology stack or that technology stack Silverlight, I have to remind myself…

It’s the people, dummy

When Did Agile Jump the Shark?

I am bullish on what agile has taught us. I am bullish on the productivity gains realized by agile teams around the world.

I groove on discovery; that is, the discovery that happens by having working software at iteration one. Discovery is fun.

But I use a lowercase “a” in agile. “a” signifies pragmatism. And, there are smells.

I invite you to have some fun considering that critical flash in time when agile Jumped the Shark.

I see Fonzie rapidly approaching across the lake on water skis.

Which option in the LinkedIn poll would you select?

Do you have an option I missed?

Dessert Only, Skip Vegetables

Dessert Only, Skip Vegetables is inspired from James Shore’s post The Decline and Fall of Agile

“…teams say they’re Agile, but they’re just planning (and replanning) frequently. Short cycles and the ability to re-plan are the benefit that Agile gives you. It’s the reward, not the method. These pseudo-Agile teams are having dessert every night and skipping their vegetables. By leaving out all the other stuff–the stuff that’s really Agile–they’re setting themselves up for rotten teeth, an oversized waistline, and ultimate failure.”
–James Shore

Dogmatic Bandwagon Traction

When colleagues start splitting hairs about what is and what isn’t agile, and when colleagues counsel against something, saying you should, or you shouldn’t, watch out! It might well be that the Method-ists are gaining traction and it could be time to get out of Dodge, or at least gallop off to the city limits.

Scrum Licenses User Groups

Does having the Scrum Alliance issue licenses to users groups strike you as regressive, or just plain silly?

If I hand you a gun, does that guarantee you’ll shoot yourself in the foot, or does it only increase the probability?

See Scrum User Group License.

Brand-Aware Conferences

Branding is cool, but branding around an open-minded approach is a sticky wicket. Brand-ism refers to an ideology, a sentiment, a form of culture, or a social movement focusing on the brand.

Brandism breeds over-zealous partisanship – like Nationalism. And authoritarian Brandism begets brand Fascism.

Software Replaces Post-It Notes

Agile software tools are a hindrance. Why?

  • Critical information is frequently obscured;
  • Several popular tools have serious usability issues;
  • They’re frequently the wrong fidelity or weight; and
  • While admittedly helpful to PMs and Scrum Masters, they’re confusing to product owners and they’re counter-productive for developers.

Simple Design or Swiss-Army Knifing?

Naresh Jain’s Managed Chaos has a short post reminding us to Embrace Simple Design.

Naresh uses the phrase:

“Smartest Possible Thing That Could Possibly Work”.

Stick that bromide in your quiver. I like that sentence.

Version One’s
marketing material refers to simple design, quoting poet Wallace Stevens

“the art of what suffices.”
Wallace Stevens

in reference to growing application functionality that is

for today’s story, and today’s story only

Sadly that advice is counter to our natural inclinations. We love to flex our muscles to unwittingly complicate things.

I sometimes feel victimized by Swiss-Army Knifing on the development team. Forget about gold plating being bereft of value to our product owners, I am referring to so-called re-usable components that well-meaning developers build. It’s an affliction that inexplicably infects the C# practitioners more so than purveyors of Java.

Many times re-usable components are a detriment to the development team who feel obliged to use them. These re-usable Rube Goldberg contraptions present technical debt we must shoehorn into our code because…well …because, um, they took so long to build?

Many of us have the unfortunate proclivity to grow do-all components; ostensibly for others to re-use. Unfortunately these knives do more than cut. Much more. So much more, they don’t even cut very well. Our Swiss Army knives end up being clunky and difficult for others to understand. Plus, they sag our pants. Turn Jam into Jelly.

Is the Swiss Army knife approach little more than the flexing of coding muscles?

In XP, the acronym is YAGNI, for

“You Aren’t Gonna Need It”

Let’s resolve to keep it simple.

I plan to heed Naresh’s advice to focus on, the “Smartest Possible Thing That Could Possibly Work”.

Thanks for the reminder.

Baffle, Befuddle, & Bewilder – Obscuring Url Tokens

Got a hankering to obscure the tokens passed along in a Url?

Say there’s a business case for obscuring integer accountIDs like accountID=2201343077108877660.

What if the accountID in the fictitious Url below was better off unknown to the user?

http://bobtuse.blogspot.com?accountID=2201343077108877660

Security-through-Obscurity might be just the ticket. Encryption is useful to obscure the ID from the user. What if the accountID visible to the user was accountID=f2z64wFzyfK1HWsWzCayh1mn0Sjktl080?

That is, the url in the address bar was

http://bobtuse.blogspot.com?accountID=f2z64wFzyfK1HWsWzCayh1mn0Sjktl080

Following are C# code snippets of two methods you’ll need. The TokenEncode method is
public static string TokenEncode(string input)
{
key = Encoding.UTF8.GetBytes(EncryptionKey.Substring(0, 8));
var des = new DESCryptoServiceProvider();
Byte[] inputByteArray = Encoding.UTF8.GetBytes(input);
var ms = new MemoryStream();
var cs = new CryptoStream(ms, des.CreateEncryptor(key, Iv), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return HttpServerUtility.UrlTokenEncode(ms.ToArray());
}

The TokenDecode method is
public static string TokenDecode(string input)
{
var inputByteArray = new Byte[input.Length];
key = Encoding.UTF8.GetBytes(EncryptionKey.Substring(0, 8));
var des = new DESCryptoServiceProvider();
inputByteArray = HttpServerUtility.UrlTokenDecode(input);
var ms = new MemoryStream();
var cs = new CryptoStream(ms, des.CreateDecryptor(key, Iv), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
Encoding encoding = Encoding.UTF8;
return encoding.GetString(ms.ToArray());
}

Also, a few class level variables that must be visible are
private static readonly string EncryptionKey = “!962Oa#ji”;
private static readonly byte[] Iv = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
private static byte[] key = {};

Usage

To obscure the accountID with TokenEncode, the C# to cobble together the Url might look like
long accountId = 2201343077108877660;
string url =
string.Format(“http://bobtuse.blogspot.com?accountID={0}”,
EncryptionHelper.TokenEncode(accountId.ToString()));

To unscramble the DES-crypto gibberish on the other end of a post with TokenDecode, the C# might look like
long accounId = Convert.ToInt64(EncryptionHelper.TokenDecode(Request.QueryString[“ID”].Trim()));

Note that TokenEncode uses the .Net methods HttpServerUtility.UrlTokenEncode and TokenDecode uses HttpServerUtility.UrlTokenDecode. Some C# code snippets I tried used Convert.ToBase64String() and Convert.FromBase64String() instead. These convert methods work until the encoded token happens to have a +/ or = in it; these characters get munged in the query string and can’t be de-coded on the post pick-up without using hack like string.replace for the errant cases.

The blog TipsForDevelopers has a good post about the Difference between Convert.ToBase64String and HttpServerUtility.UrlTokenEncode.

Paste these obfuscators into your quill. The next time you’re called upon to Baffle, Befuddle, & Bewilder, TokenEncode and TokenDecode will be at your ready.