Three types of recursive React components
You have probably used recursion by now on other, more data centring, problems, but it can be a valid approach when coding UI components. Here’s a simple take on the topic, using React.
When I think of recursive components three main cases that are worth talking about come to mind.
Purely visual
These components are mainly for flashy display. Some of them can have the self-similarity quality of geometrical fractals but in day to day web development they are required to be less visually complex than a fractal. One would consider this method when creating unique icons or backgrounds, or even wacky plots.
Taking the common element, the div, a minimal code example for this case would look like:
1 | const computeColor = (currentDept, maxDepth) => { |
The component paints a div with dome specific styles dependent on the current depth and then calls itself with an incremented depth counter. As in the case of traversing a list or a tree, this can be done iteratively instead of recursively, for a small depth value performance is not an worthwhile issue and thus it becomes a matter of which approach is more concise in the developer’s eyes.
The visual output looks as follows:
Graph data with constant display
This case has actual more real life use cases and it is the easiest case when it comes to recursive renderings. Consider having a tree or graph whose nodes represent, let’s say, the product categories in a shop and the end user would need to navigate between them. Any of these nodes can be rendered by the same panel, all being orchestrated by React’s state. I would say this is a good approach on mobile screens.
Notice that here you do not need to recursively call the component.
To enable back navigation we need a reference to each node’s parent. The approach I used is a prior parsing of data and attaching the parent to each object. For this to work, it’s important to use the same object references as this provides the freedoms to navigate the graph. I would advise to attach the parents somewhere out of the rendering flow, right after data fetching or in a useEffect hook.
1 | // pure component that renders a given node |
The code will behave as (with some minimal styles):
Graph data with unfolding display
This case is similar with the above one, only that it keeps the whole hierarchy path on screen. Almost all desktop programs implement this in menu displays. The code will use the category data from the previous example, but with a T-Shirts being split into a couple more sections.
Some key points for this case would be that now the component does call itself because we need to have multiple such visual instances on the screen at the same time. State also holds the child for which to further expand its children, and not the current node, and we don’t need a parent attached to each node because there is we don’t deal with back pagination in this case. In short, you render the a child the same way you rendered the parent node.
1 | // pure component that renders a given node's children |
Again, the a minimal styled display could look like this.
Of course, you are free to extend the handling of the item selection the way it fits your needs.
Conclusion
In a more general sense many of use have already build similar stuff, like breadcrumbs and filters that would show the same page layout but seeded by another set of items.
The mentioned cases can be extended and combined endlessly once you get the gist of it. Most likely, there is a fair amount of work to tailor for specific requirements and visual goals, but I hope this post will be a source of initial inspiration.