Display Nested Lists In ReactJS
Have you ever wanted to create a drop down of a list that users can click through? In this use case, this list has more lists and each list has more lists! I’m going to characterize this list as a JavaScript object. In this tutorial, we are going to replicate this experience step by step from scratch.
Requirements
I’m going to assume you have basic knowledge of recursion as this was inspired by it.
Starting Off fresh with create-react-app
After you have everything set up, be sure to remove any unwanted text. Add 20px to the app’s component margin. This is for readability purposes and makes the text not push against the side of the screen.
After that, we are going to add static data to our App.js file to push through our other components. Copy and paste the categories object from my github link
https://github.com/cruzgerman216/nested-lists-made-in-react/blob/main/src/App.js
Thought Process
Whenever the user clicks on each text, we want to display any content that is in “there”. Each div containing the text is going to have some sort of state in it to control expanding or condensing its content. We don’t want to iterate through this object only because we won’t control expanding or condensing the nested objects. What we have to do first is create a state-full component that allows us to show it’s content through user click.
Stateful Component to handle expanding or condensing lists
Create a folder called Components. Create a file called Block.js
Inside App.js, import Block.js and set an attribute called category to our static data and include it’s name as the key attribute so we don’t get any duplicating errors.
In our Block.js file, we want to be able to track whether or not the div expands or condenses, so create a key called on and set it to false for the state object.
To make sure everything is working, create a div and print out the objects key called name from what is passed down as a prop called category.
You can even console.log the props.data to see what is going through and kind of think about what we will be doing here. At this point, we want to click on this child div and once we do, create new elements with the same functionality as they are able to expand and condense their contents.
Create a method called expand. This method will be responsible for setting this.state.on to false or true.
To display our content, we are going to add a new key to the state called. This way, when we iterate through our object, we are going to store elements to this an array to display them. If you don’t know already, if react/jsx sees an array full of elements/components, it will display them.
Create a variable. Call it whatever you like, I called mine arr; Set it to an empty array. This array will grab sub objects from the props.data object that is being pass through.
Iterate through the object this.props.category. We want to be able to push objects to this array that don’t have the key word name because those aren’t objects but rather strings.
The idea of Recursion
This is the tricky part that’s going to require a bit of thinking. We want to be able to push new elements to this array with the same functionality of it’s parent component. The problem with this is, we can’t use recursion in a class based format only in a function based format. We can’t do this same functionality in a stateless component because we need to keep track of whether or not the div is expanding or condensing through state functionality. To solve this, we are going to create a separate file called Section.js. In this file, import Block and then include Block. Pass down props that Section receives. It’s going to seem like the Block component is recursively within it’s own component.
Change app.js to include Section.
Change the expand method in Block.js to push through Section components as we pass down new prop information. Be sure to change the state to the new formed array.
Add an onclick to the div printing the data.name
and then add a ternary operand to show this.state.data if true.
Bonus: adding style
The way we are going to keep track of styling is through the state. When iterating through the objects, make sure we don’t create a Section component for key word “style”
finally, include the style attribute to the text div.
To see full code, please visit