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.
Next page of the Free Ebook: