Ever Wondered why Recursion would ever be needed in Front-End?
Well it turns out, it's needed!
To give you a real-life example, did you ever observe how the comments for any Social Media post has reply feature to it.
Additionally, even replies have replies! Now if you notice the component or the individual comment is the same design no matter how deeply nested it is.
Yep! You guessed it right. That's where recursion is achieved in front-end from the data that you receive.
My aim with this blog is to make you understand Recursion in as simple terms and less code as possible with respect to <React/>
.
The example I am taking here is the same comment-reply inception going on around social media posts.
Here's a sneak peak into what you'll be going to make after finishing this blog. Check it out so you know what you are going to build
Now that its clear what is it all about, let's do it....!!
"Talk is cheap, show me the code" - Linus Torvalds
1. Create an Empty React Project.
Note: As this is not a CSS specific tutorial, you can directly take the corresponding stylesheet used in this project from this repo. And this is not the best UI/UX out there. So watch out xD!
2. Make a json
data which comprises of a single post information.
Here's a sample json
which I created inside my react project's src
folder.
export const postInfo = {
post: {
author: "Farhan Qureshi",
postImage:
"https://4.img-dpreview.com/files/p/E~TS590x0~articles/3925134721/0266554465.jpeg",
postDescription: "A bird chirping on the stem of a plant"
},
comments: [
{
userName: "KRK",
comment: "Ye picture hai?",
likes: 0,
replies: []
},
{
userName: "Elon",
comment: "Should I Buy It ???",
likes: 420,
replies: [
{
userName: "Parrot",
comment: "Dude! Get Some Help!!",
likes: 10,
replies: [
{
userName: "Elon",
comment: "That's it! Get into the Cage!",
likes: 300,
replies: []
}
]
},
{
userName: "Jeff Bezos",
comment: "Are you insane, Elon?",
likes: 0,
replies: []
}
]
},
{
userName: "Farhan Qureshi",
comment: "Bhai! Ye kya ladai ho raha hai mere photo pe",
likes: 100,
replies: [
{
userName: "Rancho",
comment: "Jaake tere abbu ko dikha. Khush ho jayega",
likes: 100,
replies: []
},
{
userName: "Raju",
comment: "Farhan. Photoshoot ko jaana hai camera leke aa",
likes: 20,
replies: [
{
userName: "Farhan Qureshi",
comment: "Saala sudhartha nahi thu!",
likes: 5,
replies: []
}
]
}
]
}
]
};
Tell me you already got that this post is going to be hilarious ๐
The array of comments is all we care about mostly.
3. Bring this to the App.js
De-structure out the required properties from the object.
Your Post goes like this :
import { postInfo } from "./postInfo";
import "./styles.css";
export default function App() {
const {
post: { author, postImage, postDescription },
comments
} = postInfo;
return (
<div className="Post">
<section className="author-info">
<img
src={`https://via.placeholder.com/50/7b1112?text=${
author.split("")[0]
}`}
alt={author}
/>
<h3>{author}</h3>
</section>
<img className="post-img" src={postImage} alt={postDescription} />
</div>
);
}
So far the UI looks like this
Time for the exciting part.
4. Make <Comment/>
component.
Make a component at /src/components/Comment/Comment.js
import "./Comment.css"
export const Comment = ({ currComment, author }) => {
const { userName, comment, replies, likes } = currComment;
return (
<div className="comment">
<img
src={`https://via.placeholder.com/50/7b1112?text=${
userName.split("")[0]
}`}
alt="user-profile-pic"
className="user-img"
/>
<section className="user-info">
<h3>{`${userName} ${
author && author === userName ? "(Author)" : ""
}`}</h3>
<p>{comment}</p>
<small>{`Replies - ${replies.length}`}</small>
</section>
<span>{likes} ♥</span>
</div>
);
};
currComment
prop : The exact comment which you want to showuserName
: User who posted the commentcomment
: The actual comment the user has writtenlikes
: Number of likes to the commentreplies
: The replies on the current comment ( Here's where we traverse recursively as each reply is in the similar format of an actual comment).
author
prop : Author of the post which we take from the post information. (Optional Feature just to distinguish the author of the post from the comments section if the author has commented or replied on his posts.
** Use this component in App.js
Import the Comment
component and use it in App.js
this way.
<h3>{`Comments - ${comments.length}`}</h3>
{comments.map((comment, id) => (
<div className="comment-container">
<span>{id + 1}</span>
<Comment key={id} currComment={comment} author={author} />
</div>
))}
Let's do a quick UI check :
Woaah!!! We're half way there.
Yes. It's just half-way. Now comes the hard part to recursively render the replies of comment. Or say, replies of replies of comments.
5. Handle Replies to each comment.
Points to note :
- Check whether there are replies present to an individual comment
- Make a state variable to hide/show the replies to a comment.
Now let's make few changes in Comment
component
const commentHasReplies = replies.length > 0;
const [showReplies, setShowReplies] = useState(false);
return (
<div className="comment-wrapper">
<div className="comment">
<img
src={`https://via.placeholder.com/50/7b1112?text=${
userName.split("")[0]
}`}
alt="user-profile-pic"
className="user-img"
/>
<section className="user-info">
<h3>{`${userName} ${
author && author === userName ? "(Author)" : ""
}`}</h3>
<p>{comment}</p>
<small>{`Replies - ${replies.length}`}</small>
</section>
<span>{likes} ♥</span>
</div>
{commentHasReplies && (
<p
className="fake-link"
onClick={() => {
setShowReplies((state) => !state);
}}
>
{showReplies ? "Hide Replies..." : "Show Replies..."}
</p>
)}
{showReplies
? replies.map((reply, id) => (
<div className="reply" key={id}>
<Comment currComment={reply} author={author} />
</div>
))
: ""}
</div>
);
Look at how we used Comment
component inside Component
to render the replies. That there is called recursion
.
As soon as we reach the point where there are no replies, it comes out of the recursive call and map an actual reply to the post and similarly this goes on and on till the comments end.
This is what you have made.
If you reached till this part, I request you to leave a comment about how you felt or how good was your understanding from this blog, also the areas I could improve explaining things even better. ๐๐๐
Stay tuned for more awesome blogs ๐๐๐.