It’s important to not overload your web app with unnecessary information. It’s much better to have components with expand/collapse feature. Display essential bits of information (title, category, short description) and let users expand for full information.
In this article, we will show you how to implement expand/collapse feature in React. It’s really easy.
First, let’s implement a basic expand/collapse feature without using a library. Then we’ll see how to use the react-collapsed library, which has way more functionality than a basic expand / collapse.
Specific Examples
Implement expand and collapse in React (without library)
When component is collapsed, usually it still displays some information. When it is expanded, it displays full information with details.
For example, you might have a <MovieInfo> component. When collapsed, it might display only movie name and year of the release. When expanded, it contains more information like plot, picture, list of actors, and so on.
In this blog post, we’ll use movies as an example.
Expand / Collapse React Component
You can implement expand and collapse an entire component.
Component can have two states – collapsed or expanded.
Fortunately, every React component can maintain internal state. So, we can use simple React features to implement expand / collapse functionality.
You need three basic ingredients to create a React component with expand / collapse functionality:
1. A Boolean state variable that represents current ‘state’ of the component. When it is true, component is expanded. When it is false, component is collapsed.
2. Information that is always displayed
3. A clickable area and an event handler (usually onClick).
4. Container that wraps around elements that need to be expanded or collapsed.
Let’s look at the code.
First, we need a Movie component that receives information via props.
In JSX, we always display name and year values. Later on, we’ll add information about plot and actors, which will be visible only after user clicks ‘Read More’.
We use the useState() hook to create a state variable that holds a boolean value. We name it expanded. When it is true, the component is expanded and shows full information. When it’s false, details are collapsed.
We use the onClick event handler and setExpanded function to set expanded variable to the opposite of its current value. So when the component is collapsed, clicking the button expands it, and vice versa.
import "./styles.css";
import { useState } from "react";
function Movie(props) {
const [expanded, setExpanded] = useState(false);
const { movieInformation } = props;
return (
<div className="movie">
<p>{movieInformation.name + " " + movieInformation.year}</p>
<span className="showMore" onClick={() => setExpanded(!expanded)}>
<b>Read More</b>
</span>
</div>
);
}
Our component always shows movie name and movie year.
So you can always customize bits of information that are always displayed, even when component is collapsed. In this case, that is movie name and year.
Now we’ll add a container that displays when component is expanded.
function Movie(props) {
const [expanded, setExpanded] = useState(false);
const { movieInformation } = props;
return (
<div className="movie">
<p>{movieInformation.name + " " + movieInformation.year}</p>
<span className="showMore" onClick={() => setExpanded(!expanded)}>
<b>Read More</b>
</span>
{expanded ? (
<div className="expandable">
<p>{movieInformation.plot}</p>
<p>Actors:</p>
<ul>
{movieInformation.actors.map((actor) => (
<li key={actor}>{actor}</li>
))}
</ul>
</div>
) : null}
</div>
);
}
In this case, we use curly braces to embed a ternary operator inside our JSX code.
The ternary operator looks at expanded value. If it evaluates to true, our ternary operator returns additional TV show information. If it’s false, then it returns null.
Finally, let’s create a main component where we loop through an array of objects and render <Movie> components.
export default function App() {
const movies = […];
return (
<div className="App">
{movies.map((movie) => {
return <Movie key={movie.name} movieInformation={movie}></Movie>;
})}
</div>
);
}
That’s it. You can go to live demo, see the full code and play with the code yourself.
To expand components by default, you can simply set state variable to be true by default. Simply pass true as argument to the useState() hook.
If you want expand and collapse to look smoother, you should use react-collapsed library.
Use ‘react-collapsed’ to Expand and Collapse in React
‘react-collapsed’ is an excellent utility to expand and collapse components in React.
It provides the useCollapse() hook. You can add expand/collapse functionality to any React component or any element.
When initialized, the hook returns three values:
- getToggleProps function that returns essential props for the toggle (expand / collapse). You can set it on any element. Clicking that element will expand and collapse the component.
- getCollapseProps function that returns essential props for collapsible container. The details that need to be hidden or shown depending on the Boolean state value.
- Finally, the Boolean value that represents current state of the collapsible component.
That’s all you need to implement a simple expand / collapse feature. As you can see, it also adds a simple animation, which looks much better:
You need to set getToggleProps on the toggle element, and getCollapseProps on the container that needs to be collapsed. react-collapse takes care of the rest.
You don’t need to implement any logic yourself.
Let’s look at the code:
function Movie(props) {
const { getCollapseProps, getToggleProps, isExpanded } = useCollapse();
const { movieInformation } = props;
return (
<div className="movie">
<p>{movieInformation.name + " " + movieInformation.year}</p>
<span className="showMore" {...getToggleProps()}>
<b>Read More</b>
</span>
<div className="expandable" {...getCollapseProps()}>
<p>{movieInformation.plot}</p>
<p>Actors:</p>
<ul>
{movieInformation.actors.map((actor) => (
<li key={actor}>{actor}</li>
))}
</ul>
</div>
</div>
);
}
This is pretty similar to previous code. Except, we don’t need a ternary operator, event handler, state variables. As a result, our component is much simpler.
‘react-collapsed’ doesn’t get in the way at all. It gives you the freedom to customize component’s appearance and functionality.
Configure expand/collapse – animation speed, default
‘react-collapsed’ gives you a little bit of room to specify how it should work.
You can create an object with certain properties and pass it as an argument to the useCollapse() hook.
For example, you can set the duration prop to specify the speed of animation in milliseconds.
You can set defaultExpanded to true or false to specify whether component should be collapsed or expanded by default.
Go to npm page to see the full list of options.
Note:
One disadvantage of react-collapsed (and other libraries) is that it provides hooks. So you can only use it with functional components.
Expand and Collapse div (section) in React – Example
In React, you can expand and collapse a specific <div> element.
Embed a ternary operator in JSX. If a state variable is true, show the entire div and contents inside it. If state variable is false, then keep it hidden.
You’ll also need to create an element (typically button or span) and set an event handler that flips the state variable.
Let’s see an example where we expand and collapse a section of the page:
<div>
…contents of the page
<span onClick={() => setExpanded(!expanded)}>
<b>Read More</b>
</span>
{expanded ? (
<div className="expandable">
…contents of the expanded div
</div>
) : null}
</div>
In this case, we assume the component has a boolean state variable – expanded, and setExpanded to update it.
It’s probably easier to expand and collapse a div element using ‘react-collapsed’ library. We talk about that here.
Expand and Collapse List in React – Example
Long lists aren’t easy on the eye. They usually take up too much space on the screen.
It’s better to display first few items and let users expand to see the full list. You can do that with React.
To expand and collapse list in React, first we need to render a list. Usually, we render lists by looping through the array.
We need a state variable with a Boolean value. By default, it’s going to be false, so we’ll show first three items in the list (you can show first two items, first four, or any number of items).
Once users click a button, state variable will be set to the opposite of its current value. If it’s false (as it is by default) state variable will be set to true.
We also implement the ternary operator to render the rest of items if state variable is true.
If you want expand and collapse to look a little bit smoother, use ‘react-collapsed’ library.
Let’s take a look at the code:
import "./styles.css";
import { useState } from "react";
export default function App() {
const movies = […];
const [fullList, setFullList] = useState(false);
return (
<div className="App">
{movies.map((movie, index) => {
if (index <= 2) {
return <p>{movie}</p>;
}
})}
{fullList
? movies.map((movie, index) => {
if (index > 2) {
return <p>{movie}</p>;
}
})
: null}
<span onClick={() => setFullList(!fullList)}>{fullList ? "-" : "+"}</span>
</div>
);
}
You can go to CodeSandbox to play with example code yourself.
We initialize the state variable named fullList.
In JSX, we embed two JavaScript expressions and use map() to generate JSX elements for item in the array.
We use second optional argument to the map() method, which tracks index of array item. We set the if condition to only render items up to a certain index. In this case, index is 2, so map() only renders elements for first three movies in the array.
Then we have a ternary operator, which looks at the state variable and renders the rest of items in the array if state variable is true. If it’s not, it returns null.
Finally, we have a simple button that expands and collapses a list in React.
Expand and Collapse Text in React – Example
Unnecessarily long texts are a bad UX practice. Users don’t want to see long texts unless they need them.
One solution is to allow users to expand and collapse text in React.
We will show first 30 (or any number) of characters to give users a little preview. Then we’ll display a clickable three dots (…).
If users click three dots, text will expand and they can read full text. When text is expanded, clicking three dots will collapse it again. It’ll show a preview.
Let’s look at the code:
import { useState } from "react";
export default function App() {
const [showFull, setShowFull] = useState(false);
const text =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud…”
return (
<div>
<p>
{showFull ? text : text.slice(0, 20)}
<span onClick={() => setShowFull(!showFull)}>...</span>
</p>
</div>
);
}
This is a very simple example, but it’s still very effective. Check out live demo on CodeSandbox.
In JSX, we have a ternary operator that evaluates showFull state variable. If it’s true, then our component returns full text. If it’s false, ternary operator returns first 20 characters. We use slice() method to return first 20 characters of the text.
Then we have a <span> element with three dots. We set the onClick event handler to flip the value of showFull state variable.
You can use a library like react-collapsed to add animation to beautifully expand and collapse text in React.