FIG is accepting new projects! Let’s discuss yours!

Fillmer Innovation Group

Context View Logic

April 24, 2020

The new Context API introduced in React 16.3 made quite a stir in the React community. Some are underwhelmed, some are claiming the upcoming death of Redux. Regardless, I prefer to focus on useful applications of the new pattern.

As I have begun using the new Context API I have found that I turn to it more and more to perform small, contained, view logic tasks. Some simple reusable patterns, such as tabs & modals, lend themselves very well to the Context pattern.

The Problem

As is common in an administrative UI there are many screens that are lists of data. In a recent project our list views could be in any of three states: loading, loaded with no data, or loaded with data. Using basic control structures in our JSX we end up with quite a few views that contain some variation on the following:

// Data is falsy, show Loading.
// Data is an empty array show <NoData />.
// Data is array of actual items, show <List />.
function IRecieveData ({data}) {
  return (
    <Section>
      {!data && <Loading />}
      {(data && data.length === 0) && <NoData />}
      {(data && data.length >= 1) && <List data={data} />}
    </Section>
  )
}

Nothing too crazy here, and it is simple and readable. However when we began copy and pasting multiple times throughout our application we knew it was time to generalize it and create a pattern. In our particular use-case we knew that all data coming from Redux would either be null, an empty array, or an array of items.

The Solution

function IRecieveData ({data}) {
  return (
    <Section>
      <Switch data={data}>
        <Switch.Loading render={Loading} />
        <Switch.NoData render={NoData} />
        <Switch.Data render={List} />
      </Switch>
    </Section>
  )
}

We have essentially taken our basic Javascript control structures, wrapped them with JSX; and leveraged the Context API to avoid passing data along to each component via props. What have we gained?

  1. Consistency in reuse. When leveraging this pattern in a new view simply making sure that data is mapped correctly is all that is necessary.
  2. It’s all JSX. JSX is readable, and React developers are used to reading it. This adds clarity to our code at a glance, without needing to understand the underlying data shape.

Etc.

An implementation of this pattern can be found on Github. As with most patterns in the React ecosystem, this is not appropriate for every use-case, there is no one-size fits all pattern.