Don’t get left behind! Sign up to the WebDevEducation newsletter for free tutorials, coupon codes, and more! 🎉




    Recursion explained in React JS (with example)

    First of all, let’s ask ourselves the most obvious question what is recursion?

    What is recursion?

    To put it simply, a recursive function is a function that calls itself. That’s it. Literally, it’s that simple. But then the question may be, why would we even want a function that calls itself? Or..

    What’s the point of recursion?

    Well, I’m glad you asked. The only time I’ve used recursive functions is when I’m looping over datasets that have nested data, but I have no idea how far nested that data is. We could have arrays within arrays within arrays etc etc. So then, let me show you an example.

    Headless WordPress recursion example

    The best example I have of a recursive function in its most practical application is when working with Headless WordPress. The new WordPress block editor (otherwise known as Gutenberg), allows certain blocks to contain inner blocks. So, for example, a Columns block can contain any number of single Column blocks. But, within each of those single Column blocks, we could also render a new Columns block which in turn can have any number of single Column blocks. Again, these can contain Columns with a number of Column blocks, and on and on it goes. Now, I don’t recommend designing your site with a colception design, but the point is it’s possible to have an unlimited number of inner blocks, however many levels deep. So the problem comes then, if we need to iterate over these blocks, how do we do this? Well, that’s where recursion comes in.

    recursion in next js

    The code below is taken from a snippet that’s taught in the Next JS & WordPress course, you can grab it for just $9.99 for a limited time using the link below:

    https://www.udemy.com/course/next-js-wordpress/?couponCode=JUL23A

    The code

    Let’s say we’ve got our lump of json data, which looks like this (exaggerated to prove a point):

    {
    	name: "core/post-content",
    	attributes: {
    		layout: {
    			type: "constrained",
    		},
    	},
    	innerBlocks: [
    		{
    			name: "core/columns",
    			attributes: {
    				isStackedOnMobile: true,
    			},
    			innerBlocks: [
    				{
    					name: "core/column",
    					innerBlocks: [
    						{
    							name: "core/columns",
    							attributes: {
    								isStackedOnMobile: true,
    							},
    							innerBlocks: [
    								{
    									name: "core/column",
    									innerBlocks: [
    										{
    											name: "core/columns",
    											attributes: {
    												isStackedOnMobile: true,
    											},
    											innerBlocks: [
    												{
    													name: "core/column",
    													innerBlocks: [
    														{
    															name: "core/columns",
    															attributes: {
    																isStackedOnMobile: true,
    															},
    															innerBlocks: [
    																{
    																	name: "core/column",
    																	innerBlocks: [
    																		{
    																			name: "core/columns",
    																			attributes: {
    																				isStackedOnMobile: true,
    																			},
    																			innerBlocks: [
    																				{
    																					name: "core/column",
    																					innerBlocks: [
    																						{
    																							name: "core/paragraph",
    																							attributes: {
    																								content: "",
    																							},
    																						},
    																					],
    																				},
    																			],
    																		},
    																	],
    																},
    															],
    														},
    													],
    												},
    											],
    										},
    									],
    								},
    							],
    						},
    					],
    				},
    			],
    		},
    	],
    };

    And let’s say we want to render React component based on this data. Instead of creating one giant, nested, if statement, this type of structure is a good candidate for recursion. Let’s look at the code:

    export const BlockRenderer = ({ blocks }) => {
      return blocks.map((block) => {
        switch (block.name) {
          case "core/columns": {
            return (
              <Columns
                key={block.id}
                isStackedOnMobile={block.attributes.isStackedOnMobile}
              >
                <BlockRenderer blocks={block.innerBlocks} />
              </Columns>
            );
          }
          case "core/column": {
            return (
              <Column
                key={block.id}
              >
                <BlockRenderer blocks={block.innerBlocks} />
              </Column>
            );
          }
          default: {
            return null;
          }
        }
      });
    };

    Notice that we’re rending the BlockRenderer component within itself. The BlockRenderer component will continue to render itself until there are no more blocks or inner blocks to render, regardless of however many levels deep those inner blocks are nested.


    Posted

    in

    by

    Tags: