A core concept in React is conditional rendering and without it we probably wouldn’t get very far when it comes to creating nice UI’s with good user experience built in.
This article will serve as an ultimate resource when it comes to conditional rendering in React and will be easy to follow along with no matter the level of experience you have in React, however it is assumed that you are familiar with basic JavaScript, and HTML.
React conditional rendering contains many smaller topics that we will cover such as JSX, nesting, functional components, operators, conditional statements and much more.
But the first thing we will look into will be answering the question, what is conditional rendering in React?
What is conditional rendering in React?
Conditional rendering in React is a way to display/hide/remove certain components or elements in a React application in order to create simpler, easier, and better UI and UX (user experience).
It is done by using simple JavaScript conditions in various ways to be able to selectively render parts of your application.
When we say render here, it simply means that we are allowing it to be a part of the UI and adding it in as a piece of the application.
In general, React rendering is the process by which React will add our application into a user’s window.
You can think of rendering almost like how a printer works when printing an image, but much, much faster. A printer will paint an image on a page top to bottom, once it has finished you will have a finished image, but then if you want to change something, you will have to make the change and then re-print it.
You can think of each print as the render with the printed image being the JavaScript/React application.
That is an oversimplified explanation and there is much more to it and many performance improvements but for the purposes of conditional rendering in React it should work well as an explanation.
If you would be interested in a detailed post about what rendering is in react, tweet me at @mayger_will.
React uses rendering to be able to update and refresh the application, so that each time a value changes, the relevant component will then be re-rendered in order to show the UI with the newly updated value.
Back to conditional rendering in React, when you selectively render a component or element you are preventing users from being able to see or interact with it by physically removing it from the application for that render.
For example you can hide elements with css but you can completely prevent them from being rendered with conditional rendering.
This comes in really handy for most parts of a React application and saves a lot of time and tree size(amount of elements) than in comparison to hiding things with css.
Conditional rendering is also much more secure in comparison to hiding elements or components with styles because by removing the actual data, no one can snoop around with a HTML inspector to find it (unless it has been hardcoded in the JavaScript files).
A quick guide to getting started with conditional rendering in react
Now that we know what conditional rendering is, let’s take a look at how we can start using it in our React applications.
Let’s start by making a few very simple components like so:
import React from "react";
import ReactDOM from "react-dom";
function ExampleA() {
return <p>A</p>;
}
function ExampleB() {
return <p>B</p>;
}
function App() {
return <ExampleA />;
}
ReactDOM.render(<App />, document.getElementById("root"));
The next thing to do with these components is to implement some conditional rendering!
Currently, the only part of our example that will be displayed is the component ExampleA
when our application is rendered.
But what if we might want to render the ExampleB
component instead?
This is where conditional rendering comes into play.
Let’s add in a very basic condition in order to potentially render the ExampleB component as well.
import React from "react";
import ReactDOM from "react-dom";
function ExampleA() {
return <p>A</p>;
}
function ExampleB() {
return <p>B</p>;
}
function App() {
if (true) {
return <ExampleB />;
}
return <ExampleA />;
}
ReactDOM.render(<App />, document.getElementById("root"));
As you can see the only difference here is how we have now added a very simple condition in order to start making use of React conditional rendering via in if statement.
The example will now render and display the ExampleB
component instead of ExampleA
, now this isn’t particularly useful in its current state because of how simple the condition is.
But we have a problem, where our condition has been hardcoded to true
it will always pass and therefore will always render ExampleB
.
To solve this problem and make use of the full potential of conditional rendering within React we need to make the condition parameter a variable that will be changed on a user action.
To do this we can add in a simple button and a useState react hook in order to create a toggle effect.
import React, { useState } from "react";
import ReactDOM from "react-dom";
function ExampleA() {
return <p>A</p>;
}
function ExampleB() {
return <p>B</p>;
}
function Button({ onClick }) {
return (
<button type="button" onClick={onClick}>
Toggle
</button>
);
}
function App() {
const [toggle, setToggle] = useState(true);
if (true) {
return <ExampleB />;
}
return <ExampleA />;
}
ReactDOM.render(<App />, document.getElementById("root"));
In the example we have now created our state and our button but we now need to combine it within our App so that we can toggle the two example components each time the button is clicked.
The problem here is that we are currently returning one or the other and we need to return the button component in both bits of JSX in order to make it accessible to the user.
Whilst we could just add in the button component to both, it would be a little wasteful and unnecessary to have to write it out twice, not to mention if we want to add anything further we have to add it into both places once again.
The solution to this is to make use of inline conditional rendering in React (Don’t worry we will go into this further a little later).
In order to create inline conditional rendering within React we need to make use of JSX.
Let’s take a look at how we can do that by taking a peek at the finished code from our example of conditional rendering:
import React, { useState } from "react";
import ReactDOM from "react-dom";
function ExampleA() {
return <p>A</p>;
}
function ExampleB() {
return <p>B</p>;
}
function Button({ onClick }) {
return (
<button type="button" onClick={onClick}>
Toggle
</button>
);
}
function App() {
const [toggle, setToggle] = useState(true);
return (
<>
{toggle ? <ExampleA /> : <ExampleB />}
<Button onClick={() => setToggle(s => !s)} />
</>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
In the finished example you can see we are returning a group of components in the App
component, and we have moved our conditional rendering to be performed by a ternary operator rather than an if statement.
All that the ternary statement means is that we are saying, if the toggle variable is true, return and render ExampleA
, otherwise return and render ExampleB
.
We have grouped the components in a single return statement using JSX and a fragment <> </>
, but that is another topic, for now, just think of it as a way to allow the grouping of multiple components without a parent.
By adding these few bits to our example we will now always render the Button component but conditionally render the two example components based off of a user action.
Here is how the outcome of how this react conditional rendering example looks:
React Conditional Rendering Core Concepts
By this point you should have a rough understanding of what react conditional rendering is, how it works and how to use it, probably to the point you could start using it in your React applications.
This section is going to cover some more of the core concepts to hopefully remove any confusion and answer any questions you might have.
After the core concepts, we will just step through the various different options that are available when it comes to conditional rendering in React.
The main core concept to remember is that you accept an input and based on the value of it render different components and elements.
It is no different than using if statements except that you are using it to control what is displayed via rendering components rather than anything else.
Here is a small list of the important concepts to remember when it comes to using react conditional rendering:
- You control and render different components and elements based on an input/variable.
- You will actually remove the component/element rather than just hiding it.
- It is flexible and can be used in many different ways so you should always be able to use it if needed.
- At a base level it is really no different than any other condition or conditional statement.
- Conditional rendering is one of the parts that really speeds up and helps develop UI’s in React.
If React Conditional Rendering
All conditional rendering done in React will involve some kind of condition, which could be an if statement, a ternary, an operator and so on.
Using an if statement would usually only be done within the function body of a component and not within the actual JSX because of how the code is run/returned.
In our above example we made use of both a ternary and an if statement.
Here is how react conditional rendering looks when using only an if statement:
function HomePage() {
const isAuthenticated = useAuth();
if (!isAuthenticated) {
return <Login />;
}
return <Welcome />;
}
As you can see I have emitted the imports and other noise from this example so we can focus on only what the component is doing with the conditional rendering using the if statement.
Here our component is designed to render a homepage to authenticated users.
We are using a custom react hook that will return a boolean value which will tell us if the user is authenticated.
We then pass this value into a negated if statement to see if the user is not authenticated, and if not, then we will return and render the login component so that the user is able to login.
If the user is authenticated then we will render the welcome message.
The conditional rendering here is protecting the welcome message to ensure only authenticated users can access it, and if a user logs in when the login component is rendered then the custom react hook will update to true
, and React will then render the welcome message.
If Else React Conditional Rendering
When it comes to if statements with an else statement in conditional rendering you are saying that it has to be one or the other.
In other words if you need to perform multiple checks to return multiple different components you will need to use single if statements and return statements rather than using an if else statement.
If else statements are useful if something can be rendered in only one of two ways.
With that said you will probably find it easier to avoid using if-else statements when it comes to React conditional rendering so it makes your components easier to write, work with and modify in the future.
There are exceptions to this, such as when it comes to inline conditional rendering with JSX, but in the function body they are best to avoid to prevent confusion over the two.
Here is the same example as above but using an if else:
function HomePage() {
const isAuthenticated = useAuth();
if (!isAuthenticated) {
return <Login />;
} else {
return <Welcome />;
}
}
As you can see there is no real difference except that you are ensuring that the only way the Welcome component can be rendered is if the conditional statement fails, which sometimes might be exactly what you need.
In the above example however all we have essentially done is to add a few extra lines of code for the exact same functionality.
There is nothing wrong with using an if else statement for react conditional rendering, but just be sure that it is truly needed if making use of it.
React Conditional Rendering inline JSX
Most React conditional rendering is done inline JSX. It is by far the easiest way to manipulate and format UI components to create a dynamic UI with conditional rendering in React.
When I say inline JSX I am talking about the curly braces ({}
) that you will see dotted around in React application’s JSX.
You can think of everything within the curly braces as implicitly being run and then returned into the JSX as the return value.
So if you return a string, the JSX will render that string, if you return a component then the JSX will render that component.
You can read more about rendering components in JSX here.
We will cover it in the next section but returning certain values to the JSX will render nothing, this is important to know because in JavaScript running just about any kind of code, or function will implicitly return a value (more in the next section).
For now though let’s take a look at a very simple example of React Conditional Rendering inline JSX, once again we will make use of the authentication example above:
function HomePage() {
const isAuthenticated = useAuth();
return <>{isAuthenticated ? <Welcome /> : <Login />}</>;
}
In the example in order to facilitate an inline condition that returns a value we are making use of the ternary operator which is essentially a condensed if else statement where if true we return the Welcome
component and if false we return the login component(more about ternarys in a later section).
Once again we return and conditionally render the Welcome and Login components based on the value of isAuthenticated
just like before.
Inline JSX React Conditional Rendering null and undefined
One important thing to remember when using inline conditional rendering in React is that sometimes you might only want to render a component or not render it, in other words instead of having an if-else you just want an if.
You can do this either by using a ternary with a nullish or boolean false as the else, or an operator which will implicitly return a nullish or false value if the condition does not pass.
As long as you render a null, undefined, or(Nullish) or a boolean with a value of false
then React and JSX will understand that these values should not be rendered and will ignore them.
However, whilst React will ignore a false boolean, it won’t ignore all falsy values such as 0
so you have to be careful to ensure you don’t accidentally render things you don’t want to.
A safe way to get around this is to negate the condition twice to convert it into a boolean. E.g !!exampleCondition
.
Here is an example of this with ternary:
<>{exampleCondition ? <p>Hi!</p> : null}</>
And here is an example with an operator and double negation:
<>{!!exampleCondition && <p>Hi!</p>}</>
Element variables for React Conditional Rendering
Element and component variables in React conditional rendering are simply another way in which you can share a component across different return statements.
For example, let’s say we create a button with a few properties and we don’t want to copy and paste it each time we want to use it, we could abstract it into a new component, but that might be a little too much work for what it is worth.
Another option would be to use inline conditional rendering with JSX to group the components into a single return statement.
But we can also make use of element/component variables as well.
Here is an example of this:
function ExampleA() {
return <p>A</p>;
}
function ExampleB() {
return <p>B</p>;
}
function Button({ onClick }) {
return (
<button type="button" onClick={onClick}>
Toggle
</button>
);
}
function App() {
const [toggle, setToggle] = useState(true);
const buttonComponent = <Button onClick={() => setToggle(s => !s)} />;
if (toggle) {
return (
<>
<ElementA />
{buttonComponent}
</>
);
}
return (
<>
<ExampleB />
{buttonComponent}
</>
);
}
As you can see it makes it a little easier to share that component between various return statements in comparison to copying and pasting all the props each time.
Whilst for the most part it is better to make use of React inline conditional rendering, this can still be a useful tool to remember.
React Conditional Rendering with HOC
A HOC in React (Higher Order Component) is essentially a wrapper for components. It accepts a component as a parameter and returns an enhanced version of it.
Let’s once again take our authentication example but let’s turn it into a HOC to see how we can use it to conditionally render our components.
function HomePage() {
return <Welcome />;
}
const authHoc = SomeComponent => {
const isAuthenticated = useAuth();
if (isAuthenticated) {
return <Login />;
}
return <SomeComponent />;
};
export default authHoc(HomePage);
As you can see it is very similar to the if statement method we have used before, just extracted from the HomePage
component and put inside a HOC that can be used to wrap any component.
React Conditional Rendering with multiple elements or components
The next topic in React conditional rendering is to look into how we can use it to conditionally render multiple elements or components.
By this point you might have a good idea about how you can go about doing this, if so great, but if not, don’t worry we will look at a quick example now.
Just like with any other part of creating software, there are many different ways you can conditionally render multiple elements and components, so you can be a little creative.
With that said, one of the easiest ways to do so is to make use of inline JSX once again.
So just like with our above example on inline JSX for conditional rendering, all we really need to do is add in some more components that we want to render.
Let’s take a look at that now:
function HomePage() {
const { isAuthenticated, email } = useAuth();
return (
<>
{isAuthenticated ? <Welcome /> : <Login />}
{isAuthenticated && !!email ? <p>{email}</p> : null}
</>
);
}
In the above example of conditionally rendering multiple elements/components, we have changed our example hook a little to provide us with an email field as well.
We have then used that with another ternary condition to conditionally render the users email as well as the welcome message.
React Conditional Rendering using the ternary operator
Going back to the inline JSX section where we first made use of a ternary for our conditional rendering, let’s break it down a little more here.
Just to recap this is the example we used:
function HomePage() {
const isAuthenticated = useAuth();
return <>{isAuthenticated ? <Welcome /> : <Login />}</>;
}
As I previously mentioned, you can think of a ternary in this context as syntactic sugar for writing an if-else statement in the sense it reduces the amount you need to write.
Let’s break down the ternary into each part:
ifCondition ? conditionPassed : conditionFailed;
The condition is on the left hand side ifCondition
in this case we are performing a truthy check, and then we apply the question mark symbol (?
) to say that if the outcome passes out condition (if ifCondition
is true) then return the conditionPassed
component, after that you will notice the colon :
which is the equivalent of writing else
and on the right hand side of it we provide the conditionFailed
that we want to return if the condition fails.
React Conditional Rendering using logical operators
When using inline JSX for conditional rendering in React, you are highly likely to make use of various logical operators rather than writing out ternaries all the time because it is quite common to only need to either render something or not render it.
When you make use of a ternary statement in order to render or not render something you need to explicitly return null on the else part of the condition which is’t all that fun to have to write out all the time.
Now we know that React will ignore, undefined, null and false like we have previously looked at, and because React will ignore these values it means we can make use of operators as if we are just writing a condition in the JSX rather than a whole statement.
What this means is it will make it easier to use conditional rendering within JSX.
Here is an example of how we can use the AND operator (&&
) to be able to do this:
function HomePage() {
const { email } = useAuth();
return <>{!!email && <p>{email}</p>}</>;
}
As you can see in the above we have added some inline JSX into our component, which is a condition.
This works because of how conditions work in JavaScript, each condition will be checked from left to right, if the condition fails, then it will return the failed value, if it passes then it will continue onto the next condition.
So in the above example, it first checks the double negated email value, which when it passes as true
it will then look at the <p>{email}</p>
value which is truthy and because there are no more conditions afterwards it will return the <p>{email}</p>
to the JSX causing it to render.
If the condition failed at the !!email
stage would return at that point with false
because we have double negated the email value creating a boolean false
which React will ignore.
If we had not double negated the email
value and it had failed then the value might not have been ignored and could have been rendered depending on the value returned.
Now we have an understanding of how to use logical operators when it comes to conditional rendering in React, let’s take a look at examples using the most common ones.
React Conditional Rendering using the AND operator
function HomePage() {
const { email } = useAuth();
return <>{!!email && <p>{email}</p>}</>;
}
React Conditional Rendering using the OR operator
function HomePage() {
const { email, username } = useAuth();
return <>{(!!email || !!username) && <p>{email || username}</p>}</>;
}
React Conditional Rendering using React Hooks
When it comes to conditionally rendering using React hooks it is important to remember that you must always run all hooks regardless of whether you use their values.
You cannot conditionally run React hooks.
With that said you can conditionally render components with React hooks within them, however you cannot conditionally use them within a function body.
Here is an example of what you cannot do:
function Email({ showEmail }) {
let email;
if (showEmail) {
email = useAuth().email;
}
return <>{!!email && <p>{email}</p>}</>;
}
And here is what you should do/how you can conditionally render instead:
function Email({ showEmail }) {
const { email } = useAuth();
return <>{!!email && <p>{email}</p>}</>;
}
function App() {
const showEmail = false;
return <>{showEmail && <Email />}</>;
}
React Conditional Rendering with TypeScript
Conditional rendering in React generally won’t and shouldn’t effect TypeScript values because you will still be returning the same type
For example if you conditionally render between two components you are still going to be returning a React node.
This is the same even if your component returns a null because null is still a valid React node.
React Conditional Rendering nesting
As with most nesting, if it can be avoided then you should try to avoid it because it is difficult to work with and impacts the readability of the code heavily.
With that said it is possible to nest when it comes to conditional rendering in react, you will just need to either do this via components, component body, or inline JSX.
Testing React Conditional Rendering
When it comes to testing React conditional rendering logic, it is very similar to how you would test any conditional statement.
All we need to do is look at the outcomes we get based on the values we pass in.
For example let’s say we have a component that accepts a boolean prop of a
and based on the value of it will either render one of two elements. For this scenario we would need to create two or three test cases, one for a true value being passed in and one for a false value.
The other test case here would be if no prop had been passed in, but for the purposes of this example we will just look at the first two test cases.
Let’s look into this a bit further now by first creating this component:
export function TestingExample({ a = false }) {
if (a) {
return <p>abc</p>;
}
return <p>xyz</p>;
}
Now let’s create a small test suite (using react testing library and jest)
describe("TestingExample", () => {
it('Should render abc if the prop "a" is true whilst xyz should not be present', () => {
const { getByText, queryByText } = render(<TestingExample a />);
expect(queryByText("xyz")).toBeNull();
expect(getByText("abc")).not.toBeNull();
});
it('Should render xyz if the prop "a" is false whilst abc should not be present', () => {
const { getByText, queryByText } = render(<TestingExample />);
expect(getByText("xyz")).not.toBeNull();
expect(queryByText(abc)).toBeNull();
});
});
React Native Conditional Rendering
Fortunately when it comes to React Native conditional rendering it is identical to React conditional rendering because both are using the same technology, just with different elements.
React web uses HTML elements, and React Native uses native elements, but the logic, JSX, functions, and components side to it are identical so all methods in this article apply to React native conditional rendering in exactly the same way.
Summary
There we have react Conditional Rendering, if you want more like this be sure to check out some of my other posts!