Introduction
A couple of days back I was wondering how components like these are built:
A common thing between these components is that there is a definitive pattern that gets repeated. For example, when you click on a title in the tree component, it expands. When you click on the inner title it expands and so on.
In the world of programming, to deal with these kinds of repetitive patterns we either use loops or recursions.
Everyone deals with them differently depending on their usecase. For this blogpost, I will use recursion to implement these components.
Prerequisites
I would highly recommend going through the below topics before reading this blog post:
What is Recursion?
As Sual Goodmen said, ‘Let’s just say I know a guy, who knows a guy, who knows another guy’. Recursion is similar to what he is trying to say.
From Wikipedia,
💡 **Recursion is a method of solving a computational problem where the solution depends on solutions to smaller instances of the same problem.
In laymen terms, a problem is divided into a subproblem and the solution of that is passed down to the next subproblem. This goes on till the base condition is met where base condition stops this drill down.
Let us consider a classic example of finding a factorial of a number:
So, in this function, n
is just the number we're finding the factorial for. The function keeps calling itself with n - 1
until it hits 0
. When it does, it just returns 1
. This is what we call the base case of the recursion. The return value gets multiplied with the current n
and is sent back up to the previous stack frame (which is the last time we called the function with n+1
). This cycle keeps on going until we get back to the very first function call (the original n
), and bam! We get our final factorial.
Why is Recursion?
There are a couple of advantages to using recursion that I have in mind:
- Simplicity and Readability
- Reduced Redundancy
- Divide and Conquer
You can read more about the advantages in this blog post: Recursion
Let's talk about Recursive React Elements
From the definition of recursion explained above we know that a recursive function needs a base condition that helps it to get out of the recursion state. Similar to this function, we will make use of this concept in react to create recursive elements.
Here is a visual example of a recursive element:
This recursive tree is a component based on an object that has repetitive nested children. For example, the above tree component is based on the following JSON structure:
The component that you see above is a tree component. Let us recognize some key parameters in this component from the definition of recursion:
-
Recursive state: Here the recursive state is the name or fields that are getting repeated one key within another.
As you can see this object has an
id
name
andchildren
properties. Again the children's property is an array of tree i.e. object withid
name
andchildren
properties. And this goes on and on. Base condition: In this example, the base/end case is when there are no elements to print out.
We will be building an interactive component that will help us to visualize this object in the form of a tree. So without further ado! let us get started.
Building the recursive element
What we are trying to implement is a tree that is interactive like we saw in the above section:
- We build this component out of the following tags:
-
ul
- to wrap all the list children -
li
- to present each element in the list of children -
details
- to make eachli
tag interactive. This will help it to open and close theli
tag. -
summary
- This will help to give the heading to theli
tag.
-
- So the structure is like this:
ul
wraps allli
and eachli
hasdetails
andsummary
.
Let us call this component a RecursiveTree
and create the component file for the same. Paste the below code in it:
Let me explain what’s going on here:
- We have a styled component:
StyledUnorderedList
that has the following styles:
- We loop over all the children's elements with the map function that wraps each item with the
CustomDetails
component:
- This
CustomDetails
component looks like below:
- The purpose of this component is to provide modified/additional functionalities apart from the existing
details
HTML element. Here are the additional functionalities that it provides:- You can provide icons that can be rendered in front of each element in the tree.
- For that, you need to provide an array of two icons. The first one is the open icon and the second is the close icon.
- It is to be noted that I made use of react-icons icon library.
- Interactive change of icon when the detail’s tag gets toggled.
- You can provide icons that can be rendered in front of each element in the tree.
- The component above is pretty self-explanatory and you can get a jest of out of it by a glance.
- Let us test out this component. Render this component as below and see the output:
- You can also pass your desired icons in the tree config like below:
Caveat: Event bubbling
One thing I struggled with during the implementation of this component was the toggle interaction that happened at deeper levels of the tree where getting bubble i.e. the toggle event was getting applied from the target element to all the parent elements that had event handlers that catch this toggle event.
To avoid this scenario, I made use of the e.stopPropogation
function to stop the event from bubbling.
To better explain the problem here are the visualized representations of the same:
It took me a small bit of time to understand the issue at hand but after careful debugging, I was able to resolve it.
So to provide a better interactivity in the recursive elements make sure that the events don’t get bubbled up (if that’s the desired behaviour you want).
Bonus Element!!
So this was fun. So before closing up, I would also like to share another example. This example is of recursively adding components based on a JSON config. I will just place the code below along with its output for reference.
You get the following out:
Summary
To summarize, we learned a couple of things here:
- What is recursion?
- What are recursive react elements?
- Building the RecursiveTree component
- Caveats
- Bonus Element
The entire code for this tutorial can be found here.
Thank you for reading!
Top comments (0)