CRUD Application in React.js with Hooks Example and Tutorial

    Apr 12, 2020       by Suraj Roy
React-Hooks-CRUD-Application.jpg

React Hooks are a new feature added with React 16.8. It lets us use state and other class-based component features without using Class.

What are Hooks?

React Hooks are functions that allow us to hook into React state and class-based component features from function component.

 

Function-based component example

 

 
const Example = () => {
  return <div>Function base component example</div>
}
 

 

Class-based component example

 

 
class Example extends Component {
  render() {
    return <div>I'm a class component</div>
  }
}
 

 

In this article, I am going to create a sample application to create CRUD(Create, Read, Update, Delete) application with React Hooks. I have already posted an article to create CRUD app with class based components(without hooks), You can find here CRUD Application in React Example and Tutorial

 

State Hook Example

 

Hooks added the capability to use state with functional based components, Before hooks functional based component was stateless. See the example below to under how to declare and update the value inside the state variable with the functional component.

 

 
import React, { useState } from 'react';
 
function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);
 
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
      Click me
      </button>
    </div>
  );
}
 

 

Effect Hook Example

It enables the functional component to use React life cycle methods like class-based component. See the example below:

 

 
import React, { useState, useEffect } from 'react';
 
function Example() {
  const [count, setCount] = useState(0);
 
  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
  // Update the document title using the browser API
  document.title = `You clicked ${count} times`;
  });
 
  return (
  <div>
  <p>You clicked {count} times</p>
  <button onClick={() => setCount(count + 1)}>
  Click me
  </button>
  </div>
  );
}
 

 

 

Let's Get Started

 

At first, we will create a basic react app using create-react-app tool. Run below command on terminal/command prompt to do the same.

npx create-react-app react-hooks-crud-app

 

Once the above command runs successfully. You can run it with npm start and check it over browser after typing http://localhost:3000.

 

Create Listing View

Bootstrap CSS framework will be used to add the CDN URL to the index.html file. Here CRUD operation will be performed over list of documents which will have fields title, description, publisher. We will use here dummy records. Open app.js file inside src folder and put below code in it.

 

 
import React, { useState } from 'react';
import './App.css';
import DocumentList from './components/DocumentList'
 
const App= () => {
const documentData = [
{ id: 1, docTitle: 'document1', description: 'desc1', publisher: 'publisher1' },
{ id: 2, docTitle: 'document2', description: 'desc2', publisher: 'publisher2'},
{ id: 3, docTitle: 'document3', description: 'desc3', publisher: 'publisher3' },
]
// saving value to state
const [documents, setDocuments] = useState(documentData)
 
return (
<div className="container">
<h2 className="text-center">React.js CRUD App using Hooks</h2>
 
<div className="row">
<h3 className="text-center">Document List</h3>
<div className="col-md-6 col-md-offset-3">
<DocumentList documents={documents}/>
</div>
</div>
</div>
);
}
 
export default App;
 

 

In the above code,  Below tasks have been done

  • List of documents created with dummy data
  • Value save saved to the state
  • Inside template part(inside return)
  • document list passed to a child component named DocumentList

Create DocumentList component

Create a new folder named components, and create a component file name DocumentList.js and put below code inside the fle.

 

 
import React from 'react';
const DocumentList = props =>(
 
<div className="table-responsive">
<table className="table">
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Publisher</th>
</tr>
</thead>
<tbody>
{props.documents.length > 0 ? (
props.documents.map(item => (
<tr key={item.id}>
<td>{item.docTitle}</td>
<td>{item.description}</td>
<td>{item.publisher}</td>
</tr>
))
) : (
<tr>
<td colSpan={4}>No any document available</td>
</tr>
)}
 
</tbody>
</table>
</div>
)
 
export default DocumentList
 

 

Document list data passed from parent component received through props and inside table it is rendered.

Now if you run the app on the terminal and check the app on the browser, It will look like below

react-hooks-crud-app-list

Create Document task

Create a new component named AddDocument inside the components folder and put below code inside it.

 

 
import React, { useState } from 'react'
 
const AddDocument = props => {
const initialFormState = { id: null, docTitle: '', description: '', publisher:'' }
const [document, setDocument] = useState(initialFormState)
 
const handleInputChange = event => {
const { name, value } = event.target
 
setDocument({ ...document, [name]: value })
}
 
return (
<form onSubmit={event => {
event.preventDefault()
if (!document.docTitle || !document.description || !document.publisher) return
 
props.addDocument(document)
setDocument(initialFormState)
}}>
<input type="text" name="docTitle" placeholder="Enter Title" value={document.docTitle} onChange={handleInputChange} />
<input type="text" name="description" placeholder="Enter Description" value={document.description} onChange={handleInputChange} />
<input type="text" name="publisher" placeholder="Enter Publisher" value={document.name} onChange={handleInputChange}/>
<button className="btn btn-primary">Add Document</button>
</form>
)
}
 
export default AddDocument
 

 

Update App.js

Add the below line on the top of the App.js file.

import AddDocument from './components/AddDocument';

 

Add code below state variable initialization.

// Add Document...

const addDocument = document => {

document.id = documents.length + 1

setDocuments([...documents, document])

}

 

Add view part to the App component

<div>

<h3 className="text-center">Add Document</h3>

<div className="col-md-8 col-md-offset-2">

<AddDocument addDocument={addDocument} />

</div>

</div>

 

Now if you run the app and check it over browser, The app will look like below

react-hooks-add-document-example

Now if the new document will be added through the form, It will update the state which is having 3 lists in it.

 

Update & Delete Task

 

Update App.js file for performing update end delete task. Below is the final App.js file with methods to perform add, list, edit and delete document tasks.

 

 
import React, { useState } from 'react';
import './App.css';
import DocumentList from './components/DocumentList'
import AddDocument from './components/AddDocument';
import EditDocument from './components/EditDocument';
 
const App= () => {
const documentData = [
{ id: 1, docTitle: 'document1', description: 'desc1', publisher: 'publisher1' },
{ id: 2, docTitle: 'document2', description: 'desc2', publisher: 'publisher2'},
{ id: 3, docTitle: 'document3', description: 'desc3', publisher: 'publisher3' },
]
 
const initialFormState = { id: null, docTitle: '', description: '', publisher: '' }
 
const [documents, setDocuments] = useState(documentData)
const [editing, setEditing] = useState(false);
const [currentDocument, setCurrentDocument] = useState(initialFormState)
 
// Add Document...
const addDocument = document => {
document.id = documents.length + 1
setDocuments([...documents, document])
}
// delete documents...
const deleteDocument = id => {
setDocuments(documents.filter(document => document.id !== id))
}
// set value for edit document form...
const editDocument = document => {
setEditing(true)
setCurrentDocument({
id: document.id,
docTitle: document.docTitle,
description: document.description,
publisher : document.publisher
})
}
// update document
const updateDocument = (id, updatedDocument) => {
setEditing(false)
console.log(id,'iddddd')
setDocuments(documents.map(item => (item.id === id ? updatedDocument : item)))
}
 
return (
<div className="container">
<h2 className="text-center">React.js CRUD App using Hooks</h2>
<div className="row">
{editing ? (
<div>
<h2 className="text-center">Edit Document</h2>
<div className="col-md-8 col-md-offset-2">
<EditDocument
editing={editing}
setEditing={setEditing}
currentDocument={currentDocument}
updateDocument={updateDocument}
/>
</div>
</div>
) : (
<div>
<h3 className="text-center">Add Document</h3>
<div className="col-md-8 col-md-offset-2">
<AddDocument addDocument={addDocument} />
</div>
</div>
)}
 
 
 
</div>
<div className="row">
<h3 className="text-center">Document List</h3>
<div className="col-md-6 col-md-offset-3">
<DocumentList documents={documents} editDocument={editDocument} deleteDocument={deleteDocument}/>
</div>
</div>
</div>
);
}
 
export default App;
 

 

Add edit and delete button in the DocumentList component file.

 

 
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Publisher</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{props.documents.length > 0 ? (
props.documents.map(item => (
<tr key={item.id}>
<td>{item.docTitle}</td>
<td>{item.description}</td>
<td>{item.publisher}</td>
<td>
<button onClick={() => { props.editDocument(item) }} className="btn btn-default">Edit</button>
<button onClick={() => props.deleteDocument(item.id)} className="btn btn-default">Delete</button>
</td>
</tr>
))
) : (
<tr>
<td colSpan={4}>No any document available</td>
</tr>
)}
 
</tbody>
</table>
 

 

Create a new component EditDocument inside the components folder and put below code inside it.

 

 
import React, { useState, useEffect } from 'react'
 
const EditDocument = props => {
const [document, setDocument] = useState(props.currentDocument)
useEffect(
() => {
setDocument(props.currentDocument)
},
[ props ]
)
 
const handleInputChange = event => {
const { name, value } = event.target
 
setDocument({ ...document, [name]: value })
}
 
return (
<form onSubmit={event => {
event.preventDefault()
if (!document.docTitle || !document.description || !document.publisher) return
 
props.updateDocument(document.id, document)
}}>
<input type="text" name="docTitle" placeholder="Enter Title" value={document.docTitle} onChange={handleInputChange} />
<input type="text" name="description" placeholder="Enter Description" value={document.description} onChange={handleInputChange} />
<input type="text" name="publisher" placeholder="Enter Publisher" value={document.publisher} onChange={handleInputChange}/>
<button className="btn btn-primary">Edit Document</button>
<button onClick={() => props.setEditing(false)} className="btn btn-info">
Cancel
</button>
</form>
)
}
 
export default EditDocument
 

 

The above component receives the current document through props and sets it to edit form.

If you want to use API for fetching data and update, delete to the database then install Axios within the project and use it inside the different methods(add, edit, list, delete) available to get the data and update it to the database only

 

Run the app

Now run the app with npm start and check the app on the browser. It should perform the CRUD operation perfectly. If getting any error then download the working source code from the below download option.

 

Conclusion

So in this article, We learn to create CRUD applications in React.js using Hooks step by step with the easiest approach. If you want to learn more about React Hooks click here You can also find other demos of React.js Sample Projects here to start working on enterprise-level applications.

That’s all for now. Thank you for reading and I hope this demo will be very helpful for understanding the basics of React with Hooks.

Let me know your thoughts over email demo.jsonworld@gmail.com. I would love to hear them and If you like this article, share it with your friends.

Thank you!

You can download complete code from here. Download Code


WHAT'S NEW

Find other similar Articles here: