Article image Components: Dynamic Component Rendering

6.9. Components: Dynamic Component Rendering

Page 15 | Listen in audio

In React, components are the building blocks of your application. They allow you to split the UI into independent, reusable pieces, and think about each piece in isolation. One of the most powerful features of React is its ability to render components dynamically. Dynamic component rendering allows you to decide which component to display based on various conditions, such as user input, application state, or other factors. This flexibility is crucial for creating interactive and responsive applications.

Dynamic component rendering can be achieved in several ways in React. Let’s explore some of the common methods and patterns used to render components dynamically.

Conditional Rendering

Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like if or the conditional operator to create elements representing the current state, and let React update the UI to match them.

Consider a simple example where you want to display a greeting message based on whether a user is logged in:

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <h1>Welcome back!</h1>;
  }
  return <h1>Please sign up.</h1>;
}

Here, the Greeting component renders different messages based on the value of isLoggedIn. This is a simple example of conditional rendering.

Element Variables

Another way to conditionally render components is to use element variables. You can store elements in variables and then render them as needed.

Here’s an example:

function LoginButton(props) {
  return <button onClick={props.onClick}>Login</button>;
}

function LogoutButton(props) {
  return <button onClick={props.onClick}>Logout</button>;
}

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;

    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

In this example, the LoginControl component renders either a LoginButton or a LogoutButton depending on the current state. The button variable is used to store the element to be rendered.

Inline Conditional Rendering

Inline conditional rendering is a concise way to render components conditionally using the logical AND && operator or the ternary ? : operator.

Here’s how you can use the logical AND operator:

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

In this example, the message about unread messages is only rendered if there are unread messages.

The ternary operator can also be used for inline conditional rendering:

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

Here, the ternary operator is used to choose between rendering the LoginButton or the LogoutButton.

Mapping Components

Sometimes, you may need to render a list of components dynamically. React’s map() function can be used to transform an array of data into an array of components.

Consider the following example where you want to render a list of items:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

In this example, the NumberList component takes an array of numbers and maps each number to a <li> element. The key prop is used to give each element a stable identity, which helps React identify which items have changed, been added, or removed.

Dynamic Component Loading

Dynamic component loading, also known as code splitting, is a technique used to load components only when they are needed. This can help reduce the initial load time of your application by splitting your code into smaller chunks.

React provides a built-in way to achieve this through React.lazy and Suspense. Here’s an example:

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

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}

In this example, OtherComponent is loaded only when it is needed, and a loading message is displayed while it is being loaded. This can significantly improve the performance of your application, especially if you have large components or many components that are not needed immediately.

Higher-Order Components

Higher-order components (HOCs) are an advanced technique in React for reusing component logic. They are not a part of the React API, but rather a pattern that emerges from React’s compositional nature.

A higher-order component is a function that takes a component and returns a new component. HOCs can be used to dynamically render components with additional props or behavior.

Here’s a simple example:

function withSubscription(WrappedComponent, selectData) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        data: selectData(DataSource, props)
      };
    }

    componentDidMount() {
      // Subscribe to data source
      DataSource.addChangeListener(this.handleChange);
    }

    componentWillUnmount() {
      // Clean up subscription
      DataSource.removeChangeListener(this.handleChange);
    }

    handleChange = () => {
      this.setState({
        data: selectData(DataSource, this.props)
      });
    };

    render() {
      // Render the wrapped component with the new data
      return <WrappedComponent data={this.state.data} {...this.props} />;
    }
  };
}

In this example, withSubscription is a higher-order component that subscribes to a data source and passes the data to the wrapped component. This allows you to dynamically render components with the data they need.

Conclusion

Dynamic component rendering is a powerful feature of React that allows you to create flexible and interactive applications. By using conditional rendering, element variables, inline conditionals, mapping, dynamic loading, and higher-order components, you can render components based on a wide range of conditions and factors. This flexibility is one of the reasons why React is so popular for building modern web applications.

Now answer the exercise about the content:

What is one of the most powerful features of React that allows you to decide which component to display based on various conditions?

You are right! Congratulations, now go to the next page

You missed! Try again.

Article image Components: Component Performance Optimization

Next page of the Free Ebook:

16Components: Component Performance Optimization

10 minutes

Earn your Certificate for this Course for Free! by downloading the Cursa app and reading the ebook there. Available on Google Play or App Store!

Get it on Google Play Get it on App Store

+ 6.5 million
students

Free and Valid
Certificate with QR Code

48 thousand free
exercises

4.8/5 rating in
app stores

Free courses in
video, audio and text