Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render React Component into itself, in a recursive way

I have a component say, List Component. List component can render items through component ListItem. Which can be easily achieved with something like below

import React from 'react';
import ListItem from '../list-item/list-item';

class List extends React.Component {

  renderListItems() {
    return this.props.items.map(item => <ListItem item={item} />)
  }

  render(){
    return (
      <div className="list">{this.renderListItems()}</div>
    )
  }

}

and

import React from 'react';
class ListItem extends React.Component {

  render(){
    return (
      <div className="list-item">Name: {this.props.item.name}</div>
    )
  }

}

Now, in this scenario if list items can have parent children within them i.e. one list item can further render more list items how can I render ListItem component from within itself. Following is the rendering tree I am looking for and also the state of my data

List
 - ListItem
  - ListItem
  - ListItem
 - ListItem
 - ListItem

Edit

I think right structure will be something like this

List
 - ListItem
  - List
    - ListItem
    - ListItem
 - ListItem
 - ListItem

But it will ofcourse create a circular dependency between List and ListItem components, will that be a problem?

like image 309
Umair Abid Avatar asked Sep 01 '17 15:09

Umair Abid


People also ask

Can a React component render itself?

Recursion in React Above we have an example of a recursive React component. If you look closely, you'll see that just like with the factorial function, we have a recursive call and a base case. Here, the recursive call is when the component renders itself, passing in a modified version of the props it received.

Can React components be recursive?

As previously mentioned, a recursive function is calling itself for n number of times until it reaches a base case. React components are also functions, so what if we call a react component from itself? Et voilà, we have a recursive component!

Can a component render itself?

There are four reasons why a component would re-render itself: state changes, parent (or children) re-renders, context changes, and hooks changes. There is also a big myth: that re-renders happen when the component's props change.


2 Answers

You should abstract your rendering logic into a separate method, which you can call recursively from the "render" method:

import List from 'somewhere';

class RecursiveItems extends React.PureComponent {
  constructListItem = (item) => {
    if (item.nestedItems) {
      return (
        <List key={item.key}>
          {item.nestedItems.map(this.constructListItem)}
        </List>
      )
    } else {
      return <ListItem key={item.key} item={item} />
    }
  }

  render() {
    const { listItems } = this.props

    return (
      <List>
        {listItems.map(this.constructListItem)}
      </List>
    )
  }
}

export default RecursiveItems

Completely untested code but it should give the idea.

like image 141
coconup Avatar answered Sep 28 '22 06:09

coconup


Using functional components:

//List.js
import React from 'react';

import ListItem from '../your_path/ListItem';

export default function List({items}) {
  return(
    <div className="list">
    {
      items.map(item => {
        if(item.name){
          return <ListItem item={item} />
        }
        return <List items={item} /> 
      })
    }
    </div>
  );
}


//ListItem.js: 
import React from 'react';
export default function ListItem({item}){
  return (
    <div className="list-item">Name: {item.name}</div>
  )
}

Didn't test, but I think this should work..

like image 26
Breno Oliveira Avatar answered Sep 28 '22 05:09

Breno Oliveira