fervor [>]CODING & CURIOSITY
FERVOR LEARNING SYSTEMTUTORIALS
← React

React / 10 MIN READ

Else, Ternary, Switch

Advanced conditional rendering techniques

From the original Fervor library. Examples may use older package versions.

In React, if...else if...else statements can be used in the same way as in regular JavaScript, mostly within methods or functions, to control the logic of your components. However, you cannot use if...else if...else statements directly inside JSX (the syntax extension used in React), because JSX is not JavaScript itself but an extension that gets compiled down to JavaScript.

This means that while you can’t use if...else if...else inside your return statement to conditionally render components, there are alternatives.

  1. Move logic outside of the JSX: You can write your if...else if...else statement outside of the JSX and save the result to a variable, then use that variable inside your JSX.
function MyComponent({ weather }) {
  let message;

  if (weather === 'sunny') {
    message = <p>It's sunny outside!</p>;
  } else if (weather === 'rainy') {
    message = <p>It's raining outside!</p>;
  } else {
    message = <p>The weather is uncertain!</p>;
  }

  return (
    <div>
      {message}
    </div>
  );
}
  1. Use ternary operators inside JSX: While you can’t use if...else if...else inside JSX, you can use ternary operators.
function MyComponent({ weather }) {
  return (
    <div>
      {weather === 'sunny' ? <p>It's sunny outside!</p>
        : weather === 'rainy' ? <p>It's raining outside!</p>
        : <p>The weather is uncertain!</p>
      }
    </div>
  );
}

In this example, if weather is “sunny”, it renders “It’s sunny outside!”. If weather is “rainy”, it renders “It’s raining outside!”. If weather is neither “sunny” nor “rainy”, it renders “The weather is uncertain!”.

Remember that while ternary expressions can be nested to simulate if...else if...else, this can quickly make your JSX harder to read if overused. For complex conditions, it’s often better to use the first method and move the logic outside of the JSX.

You can aldo use the switch statement in React to determine what to render based on a condition. Just like with if...else if...else statements, you can’t use switch directly inside JSX, but you can use it within a component’s rendering method to decide what to render before the JSX return statement.

Here’s an example of how you could use a switch statement in a weather component:

function WeatherComponent({ weather }) {
  let message;

  switch(weather) {
    case 'sunny':
      message = <p>It's sunny outside!</p>;
      break;
    case 'rainy':
      message = <p>It's raining outside!</p>;
      break;
    default:
      message = <p>The weather is uncertain!</p>;
  }

  return (
    <div>
      {message}
    </div>
  );
}

In this example, we define a message variable. Then, based on the value of the weather prop, we assign a different JSX element to message. This message is then included in the returned JSX.

switch statements can be particularly useful when you have many possible values for a condition, and the logic for each case is relatively simple. They can be a cleaner alternative to a long chain of if...else if...else statements or nested ternary operators.

Bonus Uses for these conditional statements

Conditional statements in React can be used for many things beyond basic show/hide functionality. Here are some cool and more advanced uses:

  1. Conditional Rendering Based on State and Props: You can choose to render different components or apply different styles based on the state of your component or the props passed in. This is great for handling user interactions or displaying different UI based on application data.
function MyComponent({ userLoggedIn }) {
  return (
    <div>
      {userLoggedIn ? <LogoutButton /> : <LoginButton />}
    </div>
  );
}

In this example, the component displays a LogoutButton if userLoggedIn is true and a LoginButton if it’s false.

  1. Feature Flags: If you’re working on a new feature and you don’t want to expose it to all users at once, you can use a feature flag. With a feature flag, you can enable or disable features in your app without having to modify your codebase significantly.
function MyComponent({ featureFlag }) {
  return (
    <div>
      {featureFlag ? <NewFeatureComponent /> : <OldFeatureComponent />}
    </div>
  );
}
  1. Error Boundaries: React 16 introduced error boundaries, which are components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the crashed component tree.
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

In this example, we use an if statement to conditionally render a fallback UI when an error occurs in a child component.

  1. Rendering Lists: You can conditionally render a message when a list is empty.
function TodoList({ todos }) {
  return (
    <div>
      {todos.length > 0 ?
        todos.map((todo, index) => <TodoItem key={index} {...todo} />) :
        <p>No todos left!</p>
      }
    </div>
  );
}

In this example, if there are no todos left, we render the message “No todos left!”.

  1. Authentication and Authorization: You can conditionally render components based on user’s authentication status or role.
function MyComponent({ user }) {
  return (
    <div>
      {user.isAuthenticated ? 
        (user.role === "admin" ? <AdminComponent /> : <UserComponent />) 
        : 
        <LoginComponent />
      }
    </div>
  );
}

Here, we render different components based on user’s authentication status and role. If the user is authenticated and their role is “admin”, we render AdminComponent. If the user is authenticated but their role is not “admin”, we render UserComponent. If the user is not authenticated, we render LoginComponent.

More

Conditional statements in React can be used for many things beyond basic show/hide functionality. Here are some cool and more advanced uses:

  1. Conditional Rendering Based on State and Props: You can choose to render different components or apply different styles based on the state of your component or the props passed in. This is great for handling user interactions or displaying different UI based on application data.
function MyComponent({ userLoggedIn }) {
  return (
    <div>
      {userLoggedIn ? <LogoutButton /> : <LoginButton />}
    </div>
  );
}

In this example, the component displays a LogoutButton if userLoggedIn is true and a LoginButton if it’s false.

  1. Feature Flags: If you’re working on a new feature and you don’t want to expose it to all users at once, you can use a feature flag. With a feature flag, you can enable or disable features in your app without having to modify your codebase significantly.
function MyComponent({ featureFlag }) {
  return (
    <div>
      {featureFlag ? <NewFeatureComponent /> : <OldFeatureComponent />}
    </div>
  );
}
  1. Error Boundaries: React 16 introduced error boundaries, which are components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the crashed component tree.
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

In this example, we use an if statement to conditionally render a fallback UI when an error occurs in a child component.

  1. Rendering Lists: You can conditionally render a message when a list is empty.
function TodoList({ todos }) {
  return (
    <div>
      {todos.length > 0 ?
        todos.map((todo, index) => <TodoItem key={index} {...todo} />) :
        <p>No todos left!</p>
      }
    </div>
  );
}

In this example, if there are no todos left, we render the message “No todos left!”.

  1. Authentication and Authorization: You can conditionally render components based on user’s authentication status or role.
function MyComponent({ user }) {
  return (
    <div>
      {user.isAuthenticated ? 
        (user.role === "admin" ? <AdminComponent /> : <UserComponent />) 
        : 
        <LoginComponent />
      }
    </div>
  );
}

Here, we render different components based on user’s authentication status and role. If the user is authenticated and their role is “admin”, we render AdminComponent. If the user is authenticated but their role is not “admin”, we render UserComponent. If the user is not authenticated, we render LoginComponent.

More

Absolutely! Here are a few more creative uses for conditional rendering in React:

  1. Dynamic Theme Switching: You can change the whole theme of your application based on a condition, such as a user’s preference for a light or dark theme.
function ThemedComponent({ theme }) {
  return (
    <div className={theme === 'dark' ? 'dark-theme' : 'light-theme'}>
      Welcome to our themed page!
    </div>
  );
}

In this example, we apply a different CSS class based on the value of theme, effectively changing the appearance of the component.

  1. Show More / Show Less Toggle: You can use conditional rendering to show or hide additional content based on user interaction.
function ShowMoreComponent({ showMore }) {
  return (
    <div>
      Here is some content.
      {showMore && <div>Here is even more content!</div>}
    </div>
  );
}

In this example, an additional content section is rendered if showMore is true.

  1. Conditional Form Fields: You can conditionally render form fields based on the value of other form fields. This can be useful in situations like registration forms, where additional information might be needed based on a user’s response to a previous question.
function RegistrationForm({ userType }) {
  return (
    <form>
      <input name="username" placeholder="Username" />
      <input name="password" placeholder="Password" type="password" />
      {userType === 'business' && <input name="businessName" placeholder="Business Name" />}
    </form>
  );
}

In this example, an additional input field for “Business Name” is rendered if userType is “business”.

  1. Lazy Loading: You can use conditional rendering to implement lazy loading in your application. With lazy loading, you can conditionally render heavy components only when they’re needed, improving the initial load time of your application.
import React, { Suspense } from 'react';

const HeavyComponent = React.lazy(() => import('./HeavyComponent'));

function MyComponent({ loadHeavyComponent }) {
  return (
    <div>
      {loadHeavyComponent ?
        <Suspense fallback={<div>Loading...</div>}>
          <HeavyComponent />
        </Suspense>
        :
        <LightComponent />
      }
    </div>
  );
}

In this example, HeavyComponent is only loaded when loadHeavyComponent is true, otherwise, a LightComponent is rendered. The Suspense component is used to display some fallback content (“Loading…”) while HeavyComponent is being loaded.

more

Sure! Here are a few more advanced and creative uses for conditional rendering in React:

  1. Context-Sensitive Actions: In an application where different user roles exist, such as ‘admin’, ‘editor’, and ‘viewer’, you might want to show different components or options based on the user’s role.
function UserOptions({ userRole }) {
  return (
    <div>
      <button>View</button>
      {userRole === 'editor' && <button>Edit</button>}
      {userRole === 'admin' && <button>Delete</button>}
    </div>
  );
}

In this example, only ‘editor’ and ‘admin’ users see the ‘Edit’ button and only ‘admin’ users see the ‘Delete’ button.

  1. Optimization with React.memo or React.PureComponent: If a component renders the same result given the same props, you can wrap it in a call to React.memo or use React.PureComponent for a class component to boost performance in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.
const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

In this example, React.memo is a higher order component. If your component renders the same result given the same props, you can wrap it in this to speed up its rendering performance by using memoization.

  1. Responsive Design: You could use conditionals to render different components or apply different styles based on the viewport size, allowing you to create a responsive design.
function ResponsiveComponent({ isMobileView }) {
  return (
    <div>
      {isMobileView ? <MobileComponent /> : <DesktopComponent />}
    </div>
  );
}

In this example, a different component is rendered based on whether the isMobileView prop is true or false, simulating a responsive design where different components are shown on desktop and mobile.

  1. Rendering with Async Data: When fetching data asynchronously, you can render different views based on the status of the request.
function AsyncComponent({ isLoading, data, error }) {
  if (isLoading) {
    return <div>Loading...</div>;
  } else if (error) {
    return <div>Error: {error.message}</div>;
  } else {
    return <div>Data: {data}</div>;
  }
}

In this example, the component renders a loading message while the data is being fetched, an error message if there was an error fetching the data, and the data once it has been fetched.

Keep your curiosity going.Explore more React →
287 TUTORIALS · 22 TOPICSREADY