DEV Community

Cover image for Recursive elements in React
Keyur Paralkar
Keyur Paralkar

Posted on

Recursive elements in React

Introduction

A couple of days back I was wondering how components like these are built:

intro-simple-tree.gif
Tree Component

intro-draw-component.png
JSON to HTML Elements

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?

what-is-recursion-i-know-a-guy.gif
Saul's Magic

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:

intro-simple-tree.gif
Tree Component

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 and children properties. Again the children's property is an array of tree i.e. object with id name and children 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 each li tag interactive. This will help it to open and close the li tag.
    • summary - This will help to give the heading to the li tag.
  • So the structure is like this: ul wraps all li and each li has details and summary.

Representation of Tree with the above elements
Representation of Tree with the above elements

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.
  • 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:

Tree with no custom icon field in the JSON object
Tree with no custom icon field in the JSON object

  • You can also pass your desired icons in the tree config like below:

Tree with custom icon field in the JSON object
Tree with custom icon field in the JSON object

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:

No event bubbling
No event bubbling

With Event bubbling
With Event bubbling

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:

intro-draw-component.png
JSON to HTML Elements

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!

Follow me on twittergithub, and linkedIn.

Top comments (0)