Dynamically add and view data using React hooks — useState, useEffect, useRef

Vidisha Pal
5 min readMar 21, 2022

--

We have a simple blog screen the lets us view a list of comments made by readers of our blog.

Previously, we have created a blog page to view reader comments and added styling to our page. The details can be found here

Now, we want to let readers add new comments to our blog. For this feature, we will use react useEffect and useState hooks.

Our react app has two components, Comments.js and Comment.js.

Comment.js file displays each comment.

Comments.js renders a list of comments as well as the dummy blog content.

Comments.js

The Comments.js has a variable that contains a list of comments.

This list is iterated and for each object in the list a Comment component is rendered.

We also have a textarea to add a new comment and a button to post the comment to our blog.

import React, { useState } from "react";
import Comment from './Comment';

const commentsList = [
{
name: 'Sally',
description: 'I really loved reading about your blog!'
},
{
name: 'Mary',
description: 'Great work! Definitely inspired me to add more green to my place.'
},
{
name: 'Andrea',
description: 'Thanks for the guide to buying houseplants for beginners.'
}
];

const addCommentHandler = () => {
console.log('addCommentHandler clicked');
}

function Comments() {
return (
<>
<div className="container">
<h2>My Amazing Blog</h2>
<hr />
<br />
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<p>
Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.
</p>
</div>
<br />
<div className="container">
<h4>Comments</h4>
<hr />
<br />
</div>
<div className="container">
<div className="row justify-content-start">

<div className="col xl-2 lg-2 md-3 sm-4 xs-4">
<textarea
className="form-control"
placeholder="Leave a comment here"
>
</textarea>
</div>
<div className="col xl-1 lg-1 md-1 sm-2 xs-2">
<button
type="button"
className="btn btn-outline-secondary"
onClick={addCommentHandler}
>
Post comment
</button>
</div>
<div className="col xl-10 lg-10 md-10 sm-6 xs-6">
</div>
</div>
</div>

<br />

{commentsList.map(
(comment, index) => <Comment
key={index}
name={comment.name}
description={comment.description}
/>
)}
</>
)}

export default Comments;

The button element has an onClick event handler. On clicking the button, the addCommentHandler function is called.

<button 
type="button"
className="btn btn-outline-secondary"
onClick={addCommentHandler}
>

The function addCommentHandler does not do anything at the moment. It just prints out a message in the browser console.

const addCommentHandler = () => {
console.log('addCommentHandler clicked');
}

Set comments with useEffect and useState hooks

Suppose that the comments are loaded from a database instead of being stored in a variable.

This is a practical use case where we have to load and display comments after getting the data from a different server or a database.

How do we store and display comments the first time the page loads and on consecutive reloads or when data changes?

This is where useState and useEffect hooks are used.

useState hook allows us to store a stateful value and also provides a function to change that value.

For our blog, we can initialise the commentsList with a useState hook. When we add a new comment, we update this list with the new value.

First, we import both useEffect and useState hooks.

import React, {useEffect, useState } from "react";

Next, we initialise a useState hook called comments with an empty list. We also define a function setComments that will allow us to change the comments list.

We also set a loading useState hook that is initialised to true.

const [comments, setComments] = useState([]);
const [loading, setLoading] = useState(true);

We set the comments defined above to a list of values when the page first loads. For this, we use the useEffect hook.

The anonymous function in the useEffect will run after the component render is complete.

We are setting the comments variable to the list of comments and also setting loading to false.

useEffect(() => {
setComments(commentsList);
setLoading(false);
}, []);

Finally, we need to update rendering the Comment component to use the comments useState hook.

{!loading && comments && comments.length> 0 && commentsList.map(
(comment, index) => <Comment
key={index}
name={comment.name}
description={comment.description}
/>
)}

Retrieve new comment with useRef hook

Let us now see how to retrieve the new comment when user clicks on the button.

To implement this feature, we will use the useRef hook.

The ref object’s current property holds a reference to the DOM node that the hook refers to.

First, we need to import the useRef hook in Comments.js

import React, {useEffect, useState, useRef} from "react";

Next, we initialise the useRef hook with an initial value of null.

const commentsRef = useRef(null);

We have a reference to the commentsRef in our textarea element.

Whenever we type a comment, we can access this value by using the commentsRef.current.value property.

<textarea
className="form-control"
placeholder="Leave a comment here"
ref={commentsRef}>
</textarea>

Finally, to access the new comment when a user clicks on the button, we add the following lines to the function addCommentHandler.

We access the value of the new comment with commentsRef.current.value.

Then we update the comments list set by the useState hook to the updated list. We assume a dummy user called ‘Wendy’ is adding new comments.

const addCommentHandler = () => {
if(commentsRef.current && commentsRef.current.value) {
let updatedComments = comments;
updatedComments.push(
{ name: 'Wendy',
description : commentsRef.current.value
}
)
setComments([...comments] , updatedComments);
}
}

Adding new comments

Finally, when we add new comments, we can see that they are displayed in comments list.

Thank you for reading!

--

--