Read in React.js CRUD Operations

Introduction

In my previous article, I explained the MERN Stack, MEN Stack, and 'View' aspects within the MVC architecture with the fundamentals of React. Additionally, it discusses CORS security features with examples.

  1. MVC Architecture With Node.js CRUD Application [Node.js-Express-MongoDB]
  2. View in React.js within the MVC Architecture
  3. Impact of React in MERN Stack Development

I have attached a zip file containing the source code for the Node.js API and React.js in this article.

Read operation in CRUD

In the context of React.js, "CRUD" refers to the basic operations that can be performed on data: Create, Read, Update, and Delete. These operations are essential in the development of applications that interact with a database or manage data in some form. The "R" in CRUD stands for "Read," and it plays a crucial role in displaying data in a React application.

The role of "R" (Read) in React.js CRUD operations

1. Fetching Data

  • The "Read" operation involves retrieving data from a data source, such as an API or a local database.
  • In a React application, you typically use lifecycle methods or hooks to fetch data from an API when a component mounts.

2. Displaying Data

  • Once the data is retrieved, the "Read" operation involves displaying it in the user interface.
  • React components are responsible for rendering the data and presenting it to the user.

3. State Management

  • React components often use state to manage the data that they display.
  • When data is fetched, it is typically stored in the component's state, triggering a re-render to reflect the updated data in the UI.

4. Conditional Rendering

  • The "Read" operation may involve conditional rendering based on the presence or absence of data.
  • React components can conditionally render different UI elements based on whether the data has been successfully fetched or if it is still loading.

We can observe the emergence of a new term in State Management. What is State Management? State Management is a vast topic, and I have limited space to delve into it in this article. Let's explore the fundamentals of State Management in React.

Fundamentals of State Management in React

In React.js, state management refers to the process of handling and managing the internal state of a component. The state represents the data that a component needs to keep track of and render accordingly. The state is essential for creating dynamic and interactive user interfaces.

React components can have two types of data: props and state. While props are used for passing data from a parent component to a child component, the state is used for managing a component's internal data that can change over time due to user interactions, network requests, or other factors.

There are two main ways to manage the state in React.

  1. Class Components.
  2. Functional Components with Hooks.

In our article and project, we are using the Functional Components with Hooks.

Functional Components with Hooks

With the introduction of hooks, especially the useEffect and useState hooks, functional components can now manage state as well. Hooks provide a way to use state and other React features in functional components.

Let's practically start fetching data to build upon my previous articles. View in React.js within the MVC Architecture

Share the app.js here.


import './App.css';
import axios from "axios";
function App() {

  const loadStudentData = async () => {
    const res = await axios.get("http://localhost:5000/api/student");
    console.log("<<<Get Student Data>>>>", res.data)
  };
  return (
    <div className="App">
      <header className="App-header">
        <p> My Project :</p> 
       <button onClick={loadStudentData}>Click to retrieve student data.</button>        
      </header>
    </div>
  );
}
export default App;

Just, I simply create a button, click, and call the loadStudentData function.

loadStudentData as an async arrow function (=>).

const loadStudentData= async () => {
  const res = await axios.get("http://localhost:5000/api/student");
  console.log("<<<Get Student Data>>>>", res.data)
};

Function, it uses Axios, specifically the axios.get() method, to send an HTTP GET request to "http://localhost:5000/api/student" to fetch data from that API endpoint.

After successfully fetching the data, it logs "<<<Get Student Data>>>>" along with res.data to the console.

Local host

Picture 01. Successfully fetching data to the console.

Fetching Data

Let's begin fetching data before diving into the understanding of useState and useEffect.

useState

The useState hook is used to add state to functional components in React. It returns an array with two elements: the current state value and a function that allows you to update it.

  const [data, setData] = useState([]);

useEffect

The useEffect hook is used for handling side effects in functional components. Side effects can include data fetching, subscriptions, manually changing the DOM, and more. useEffect takes two parameters: a function that contains the code for the side effect, and an optional array of dependencies.

useEffect(() => {
   // This function will be executed after the component is rendered
   fetchData(); // Some function to fetch data
   // Cleanup function (optional)
   return () => {
     // Code to clean up or cancel the effect (e.g., clearInterval, clearTimeout)
   };
 }, []); // Dependency array is empty, so the effect runs only once after the initial render

The useState and useEffect functions come from React. First, we need to import both. import React, { useEffect, useState } from "react";

Create a useState

  const [data, setData] = useState([]);

Create a fetch function

  const fetchStudentData = async () => {
    const res = await axios.get("http://localhost:5000/api/student");
    setData(res.data);
  };

Create a useEffect and call the fetchStudentData function inside it.

   useEffect(() => {
      fetchStudentData();
    }, []);

It is executed after the component has rendered fetchStudentData.

import React, { useEffect, useState } from "react";
import './App.css';
import axios from "axios";

function App() {
   const [data, setData] = useState([]);

   useEffect(() => {
      fetchStudentData();
    }, []);
 
  const fetchStudentData = async () => {
    const res = await axios.get("http://localhost:5000/api/student");
    setData(res.data);
  };

console.log("StudentData >>>", data);
  return (
    <div className="App"> <h1>Students Data </h1> </div>
  );
}

export default App;

I'm not returning anything here. I am only fetching the data and getting the value in the console.

Console

Picture 02. Successfully fetching data to the console.

Now I’m going to map the fetched-out student date.

Data

Picture 03. Fetch data Table View.

We need to incorporate the table view, so now I'm obtaining an HTML table.

Inside of src folder, create a new page of the table.jsx

table.jsx

Picture 4. new page of table.jsx.

Now I’m sharing a table.jsx code.

Table head name map: Assuming data is an array of objects with keys representing column names.

Here collect Columns name in columns variable.

  const columns = Object?.keys(data);

Here is the Column name mapping.

{columns.map((column, index) => (<th key={index}>{column}</th>))}

This is the beginning of a JavaScript expression inside JSX. It uses the map function to iterate over each element in the data array.

<tr key={row._id}>: For each element in the data array, a table row (<tr>) is created.

The key attribute is set to the value of row._id.

In React, the key is used to uniquely identify each element in a list, helping React to efficiently update and re-render components.

 {data.map((row) => (
          <tr key={row._id}>
            <td>{row._id}</td>
            <td>{row.name}</td>
            <td>{row.address}</td>
            <td>{row.dateOfBirth}</td>
            <td>{row.gender}</td>
            <td>{row.phoneNum}</td>
            <td>{row.createdAt}</td>
            <td>{row.updatedAt}</td>
            <td>{row.__v}</td>
          </tr>
        ))}

Here you can see the full table view in table.jsx.

const Table = ({ data }) => { };: This defines a functional component named Table. The component takes an object as its argument, and it uses a destructuring assignment to extract the data property from that object.

import React from "react";

const Table = ({ data }) => {

  // Assuming data is an array of objects with keys representing column names
  const columns = Object?.keys(data);

  return (
    <table border={2}>
      <thead>
        <tr> {columns.map((column, index) => (<th key={index}>{column}</th>))}  </tr>
      </thead>
      <tbody>
        {data.map((row) => (
          <tr key={row._id}>
            <td>{row._id}</td>
            <td>{row.name}</td>
            <td>{row.address}</td>
            <td>{row.dateOfBirth}</td>
            <td>{row.gender}</td>
            <td>{row.phoneNum}</td>
            <td>{row.createdAt}</td>
            <td>{row.updatedAt}</td>
            <td>{row.__v}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
};
export default Table;

Now I’m going to import the table page. import Table from "./component/table";

<Table data={data} />: it means you are rendering an instance of the Table component and providing it with a prop called data, and the value of data is the data you want the Table component to work with. <Table data={data}/>

Here you can see the full code of App.js.

import React, { useEffect, useState } from "react";
import './App.css';
import axios from "axios";
import Table from "./component/table";


function App() {
   const [data, setData] = useState([]);

   useEffect(() => {
      fetchStudentData();
    }, []);
 
  const fetchStudentData = async () => {
    const res = await axios.get("http://localhost:5000/api/student");
    setData(res.data);
  };

  return (
    <div className="App">
    <Table data={data}/>
    </div>
  );
}


export default App;

Here you see the mapped table view.

Table view

Picture 7. Mapped table view.

Summary

The article "React.js CRUD: Role of Read" delves into the significance of the "Read" operation in React.js CRUD applications. It covers fundamental concepts such as MVC architecture, MERN/MEN stacks, and the role of the "View" in React. The "Read" operation involves fetching, displaying, and managing data, and the article introduces state management using functional components with hooks.

A practical example demonstrates data fetching using Axios, and the article explores the useState and useEffect hooks. It then explains the use of the map() function to display fetched data. The article concludes by creating a table view for the data and integrating it into the React application.

Overall, the article provides a comprehensive guide to the "Read" operation in React.js, emphasizing data fetching, state management, and rendering techniques through practical examples. I have attached a zip file containing the source code for the Node.js API and React.js in this article.

This content is tailored for individuals interested in self-learning. Feel free to stay connected with me for more updates.


Adelanka (PVT) LTD
Globally based Software Developing & Data Processing Company