Conditional React: 3 Ways To Control Your Component Flow

Conditional React: 3 Ways To Control Your Component Flow

ยท

6 min read

If you've written any code, you've probably come across control flow.

But what is it?

Here's what MDN says about control flow:

The control flow is the order in which the computer executes statements in a script.

So control flow describes what parts of your code run and in what order. Cool...but that's not that interesting. It would be more valuable if we could manipulate the control flow and change your code's execution order.

Luckily most programming languages have built-in ways to do this.

While React isn't a programming language in its own right, it relies heavily on the fundamentals of JavaScript. Understanding how JavaScript deals with control flow will help you write flexible React components that change how they render.

There are 3 core ways to control how your components render.

1. The if/else statement

The most common conditional is the basic if/else statement:

function myFunc(name) {
    if (name === 'thesshguy') {
        return 'Cool';
    }
    return 'Not Cool';
}

An if/else statement lets you return early when some condition is met. This same principle can be used in your React components. You can return different JSX elements based on the value of a prop:

Notice how we return different JSX based on the name prop.

Try changing the names to see what happens.

2. The ternary operator

If you've never seen a ternary operator before, it might look a little confusing at first.

The ternary operator takes three inputs and returns a single value. The three inputs are a condition, a truthy value, and a falsy value. Truthy and falsy just mean values that are considered true or false when converted to a Boolean.

All ternary operators follow the same format in JavaScript:

  1. A condition followed by a ?

  2. An expression to execute if the condition is truthy followed by a :

  3. An expression to execute if the condition is falsy

Note: If that's still not clear, you can use the handy acronym W.T.F. to help you remember: what (cond) ? true : false.

function myFunc(name) {
    /*
     * W.T.F.
     * 1. What: name === 'thesshguy'
     * 2. True: 'Cool'
     * 3. False: 'Not Cool'
     */
    return name === 'thesshguy' ? 'Cool' : 'Not Cool';
}

If that sounds familiar, it should.

The ternary operator is often used as an alternative to the if/else statement.

Let's rewrite the example above using a ternary operator:

Easy!

But why would you ever choose to use the ternary operator? Is the only difference the syntax, or are there other benefits?

Great questions!

Ternary operators can be used in JSX

One drawback of the if/else statement is that it can't be used inside of JSX:

function MyComponent() {
    return (
        <div>
            {
                if (someCondition) {
                    return 'True';
                }
            }
        </div>
    );
}

The reason you can't do this has to do with how JSX is converted to HTML under the hood. If you want an in-depth explanation, you can read my post about how React converts JSX to HTML. If you want to skip that post (I totally understand if you do ๐Ÿ™‚), here's a quick recap.

When your React code is built, the above gets converted to the following:

function MyComponent() {
    return React.createElement(
        'div',
        {},
        if (someCondition) {
            return 'True';
        }
    );
}

A JSX element's children are passed as arguments to React.createElement.

The issue is that an if/else statement can't be used as a value in JavaScript. It can't be passed as a function argument. Since it doesn't have a value, JavaScript can't do anything with it.

It's not a limitation with React, but rather a limitation with JavaScript.

On the other hand, a ternary operator can be used in JSX for the same reason. It resolves to a value that can be passed to React.createElement. This means the following will work:

Another benefit is that this pattern lets us DRY up our code. We don't need to repeat the <div></div> for both conditions.

3. The Logical AND (&&) operator

The final way to render things conditionally in React is with the Logical AND (&&) operator.

The Logical AND takes two inputs separated by the && operator. If the first value is truthy then the second value is returned. If the first value is falsy then the first value is returned:

function LogicalANDExample() {
    return true && 'Hello'; // returns 'Hello'
    return false && 'Hello'; // returns false
}

This same idea can be used to render JSX elements in a React component. If you make the second value a JSX element, you can conditionally render it based on the first value:

If props.name equals the string thesshguy, we return the JSX, otherwise, we return false.

It should be clear why the second div no longer shows up. The condition is false so we don't return the div in that case. But what about the value that we are returning?

What the heck happened to the false value and why didn't React render it?

React doesn't render (some) falsy values

Let's say you have a situation where you don't want to render anything.

React allows for this by letting you return certain falsy values. The most common value that's used for this is null:

function EmptyComponent() {
    return null;
}

function App() {
    // I do not render anything
    return <EmptyComponent />;
}

This is also the case for undefined and false, which is why in the example above, nothing is rendered for the second <CoolChecker name="otherguy" /> element.

What about 0?

One thing that trips up new React developers is the value 0. While it is falsy, when you use it as the first value of the Logical AND operator, React still renders it:

This can be a bit confusing at first, but it makes sense why React would do this.

There are legitimate reasons why you'd want to render 0. For example, maybe you want to show a countdown on the page. If React didn't render 0, you'd have to convert it to a string first.

So how do you get around this issue?

The easiest way is to make sure you return false instead:

function RenderCount(props) {
  return props.count > 0 && <div>Count is {props.count}</div>;
}

One way to do that is with a comparison operator like greater than. Not only does props.count > 0 always return a boolean, it also makes the intention of the code more clear.

Win-Win!

Conditionals for JSX assignment

JSX isn't limited to return statements.

You can assign JSX to a variable. This lets you reuse the JSX in multiple places and keeps the code clean. Variable assignment can take advantage of all the conditional logic that's been mentioned above:

function MyComponent() {
    let first;
    if (someCond) {
        first = <div>The if/else statement is true!</div>;
    }

    const second = (
        <div>
            The ternary is {someCond ? 'true!' : 'false!'}
        </div>
    );

    const third = someCond && <div>The Logical AND is true!</div>;

    return (
        <div>
            {first}
            {second}
            {third}
        </div>
    );
}

What's great about all the examples above is that they rely on standard JavaScript functionality.

By learning how to manage control flow for your React components, you become a better JavaScript developer!

ย