The Case for <Row> (and <Col>)

React Native’s base set of components are amazing! <View> enforcing flexbox and defaulting to {flexDirection: 'column', position: 'relative'}? So smart.

It is such a successful set of components and constraints that web developers (like me) are bringing them to the web. See react-native-web and react-primitives for two great examples of this.

Now, this is getting a bit nitpicky, but I believe there is a good case for adding just a couple more layout components to your toolkit. Whether these components should exist at the framework, primitive level or in user-space is up for debate.

The Problem

Given what we know about View, how do you expect the code below to render in your app?

Well, because View defaults to flexDirection: 'column', and there are no style overrides, I expect the text to render as I read it: top-down.

What if I add another View into the code?

No change here. The direction of each is still column, so I can read it top-down.

Now let’s add some styles to these Views. How will they render?

Hmmm, all of a sudden, when reading my JSX, I don’t know that they’ll render top-down. Either of these newly introduced styles may modify the flexDirection. So, I need to jump to the code that defines these styles to figure out how I should read the JSX. This jumping back and forth inhibits the skimability and efficiency of your code. It is like reading a technical book, where you frequently need to look up words in a dictionary.

The Solution

Let’s add Row into the mix. Row, for now, just forces its flexDirection to 'row'. How do you expect this to render?

As I read top-down within Row, I know it'll render left-right.

Another example:

Within View, since there isn't a style prop, I can read top-down. Then when I step in to Row, it tells me I should read left-right.

Now, we could just stop here with adding Row to our toolkit, but View will often have a style prop, so lets formalize things with adding Col as well. Col, for now, just forces its flexDirection to 'column'.

Cool, now I know that I can read top-down within Col, despite it having a style prop. And I know that I can read left-right within Row, despite it also having a style prop.

Hot dang! That’s some nice and easy reading.

When To Use View

In this new system, View is still necessary for two use cases:

1. A variable flexDirection

View signals to the reader that they can't just keep skimming here. They need more context to know if they should read top-down, left-right, bottom-up, or right-left.

2. It only has one child

With one child, the direction does not matter, so we signal that to the reader by using View.

Going Further

With constelation, the prototyping framework my team uses, we’ve taken Row and Col a bit further by adding alignVertical: 'top' | 'center' | 'bottom', alignHorizontal: 'left' | 'center' | 'right', reverse for 'column-reverse' and 'row-reverse', and some other convenience props.

This post has already gotten longer than I intended. If you have any more questions, please check out the full write-up in the react-playbook.