Hi, here we want to make a simple crud app with react hooks
by using json-server
, axios
and Tailwind CSS
for styling.
In this app we have two fields: name, username with three default values that we can edit, delete them or add a new one.
You can find source code here: source code
let's start this project together step by step:
1. Setup project
Run npx create-react-app react-crud-app
to create a new app. Open the project and run npm start
to see the project in your browser and then open a new terminal and run this command to start json-server :npx json-server --watch data/data.json --port 8000
2. Files & Folder
we just need App.js file and delete other files. Then create two folders: components
& data
.
Components :
In the src
folder, create a components
folder to put all of our files inside it. We have four components inside this folder :
AddUser.js
: to add a user
EditUser.js
: to edit a user
UserList.js
: to show all users
Home.js
: it is our homepage
data:
It is in the root folder. Inside this folder create a file and called it data.json
and put all of our data inside it.
{ "users":[ { "name":"Negin", "username":"negin007", "id":1 }, { "name":"Craig", "username":"benisphere", "id":2 }, { "name":"Ben", "username":"siliconeidolon", "id":3 } ] }
3. Code
App.js:
add path for components by using react-router-dom
:
import React from 'react'; import { Routes, Route } from "react-router-dom"; import Home from './components/Home'; import EditUser from './components/EditUser'; import AddUser from './components/AddUser'; const App = () => { return ( <> <Routes> <Route path='/' element={<Home />} /> <Route path='/edit/:id' element={<EditUser />} /> <Route path='/create' element={< AddUser />} /> </Routes> </> ); } export default App;
Home.js:
This is your home component, where you can see a list of users (UserList.js
) and add a new user(AddUser
).
Also, here we have a useEffect
to fetch all users and a function(deleteUser
) for deleting a user.
import axios from "axios"; import { useEffect, useState } from "react"; import UserList from "./UserList"; import AddUser from "./AddUser"; const Home = () => { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { setLoading(true) axios.get("http://localhost:8000/users") .then(response => { setUsers(response.data) }) setLoading(false) }, []) const deleteUser = (id) => { axios.delete(`http://localhost:8000/users/${id}`).then((response) => { const newUser = users.filter((user) => user.id !== id); console.log(response) setUsers(newUser); }).catch(error => { console.log(error) }); } return ( <div className="max-w-xl pb-8 mx-auto px-5 bg-slate-100"> <UserList users={users} loading={loading} deleteUser={deleteUser} /> <AddUser users={users} setUsers={setUsers} /> </div> ); } export default Home;
UserList.js:
A component for showing list of users.
Here we're passing users
, loading
, deleteUser
as props to this component: users
: list of users, loading
: for the time before user loaded on the page and deleteUser
function for deleting a user.
Another important thing in this component is edit button:
we wrap it inside a Link
component and then when user click on this button it navigates to EditUser
component.
import { Link } from "react-router-dom"; const UserList = ({ users, loading, deleteUser }) => { return ( <div className='py-5'> {loading && <p>loading ...</p>} {users && <ul> {(users.map((user) => <li className='flex justify-between border-b-4' key={user.id}> <div className="flex "> <p className='my-3 px-3'>{user.name}</p> <p className='my-3 px-3'>{user.username}</p> </div> <div> <Link to={`/edit/${user.id}`}> <button className='mx-2 my-3 px-2 py-1 text-green-800 hover:bg-green-400 hover:rounded-md hover:border hover:border-green-800' >EDIT</button> </Link> <button className='my-3 px-2 py-1 text-red-800 hover:bg-red-400 hover:rounded-md hover:border hover:border-red-800' onClick={() => deleteUser(user.id)} >Delete</button> </div> </li> ))} </ul > } </div > ) } export default UserList;
AddUser.js:
It is a form with two input fields (name & username) and a button to submit a new user. Here we pass setUsers
, users
as props to this component.
For submitting a new user we have handleSubmit
function and inside this function we make a post request to post new name and username and the pass it to setUsers
and then make the fields empty.
import React, { useState } from 'react'; import axios from "axios"; const AddUser = ({ setUsers, users }) => { const [name, setName] = useState("") const [username, setUserName] = useState("") const handleSubmit = (e) => { e.preventDefault(); axios .post(`http://localhost:8000/users`, { name, username }) .then((res) => { setUsers([...users, res.data]) setName(''); setUserName(''); }); }; return ( <form onSubmit={handleSubmit}> <div className='flex flex-col justify-center items-center sm:flex-row sm:justify-evenly'> <div className='mb-2'> <input className='px-3 py-1 rounded-full border border-gray-600' value={name} onChange={(e) => setName(e.target.value)} required type="text" placeholder="Name" /> </div> <div className='mb-2'> <input className='px-3 py-1 rounded-full border border-gray-600' value={username} onChange={(e) => setUserName(e.target.value)} required type="text" placeholder="UserName" /> </div> <div className='mb-2'> <button className="bg-blue-500 hover:bg-blue-700 text-white py-1 px-3 rounded-full"> Add </button> </div> </div> </form> ); } export default AddUser;
EditUser.js:
This component is for editing each user, after click on edit button then we navigate to this component. Here we have a useEffect
for loading the data that we want to edit and then a handleSubmit
function for submitting the edited item.
import axios from "axios"; import { useEffect, useState } from "react"; import { useNavigate, useParams } from "react-router"; const EditUser = () => { const [data, setData] = useState([]) const [name, setName] = useState(''); const [username, setUserName] = useState(''); const { id } = useParams(); const navigate = useNavigate() useEffect(() => { axios.get("http://localhost:8000/users/" + id) .then(response => { const data = response.data; setName(data.name); setUserName(data.username); }) .catch(error => console.log(error)) }, [id]) const handleSubmit = (e) => { e.preventDefault() axios.put("http://localhost:8000/users/" + id, { name, username }) .then(response => { setData(response.data); navigate('/') }) } const goHome = () => { navigate('/') } return ( <div className="flex items-center justify-center"> <form onSubmit={handleSubmit}> <div className='flex flex-col justify-center items-center bg-slate-100 p-10 mt-10 rounded-md'> <input className='my-2 px-5 py-1 rounded-full border border-gray-600' type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} /> <input className='my-2 px-5 py-1 rounded-full border border-gray-600' type="text" placeholder="UserName" value={username} onChange={(e) => setUserName(e.target.value)} /> <div className="flex my-2"> <button className='text-white mx-1 px-5 py-1 rounded-full bg-blue-500 hover:bg-blue-700'> EDIT </button> <button onClick={goHome} className='text-white mx-1 px-5 py-1 rounded-full bg-blue-500 hover:bg-blue-700' > CANCEL </button> </div> </div> </form> </div> ); } export default EditUser;
Now here we go! We created a simple crud app
with react-hook
, json-server
, Axios
and Tailwind CSS
. In the below I put links that are helpful for me to create this project:
Build a CRUD App in React with Hooks
Thank you for reading! 🍀
Top comments (0)