DEV Community

Cover image for Crud-react-app with json-server and axios
Negin Saljooghi
Negin Saljooghi

Posted on • Updated on

Crud-react-app with json-server and axios

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

project home page
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
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode
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;
Enter fullscreen mode Exit fullscreen mode
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;
Enter fullscreen mode Exit fullscreen mode
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;
Enter fullscreen mode Exit fullscreen mode
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;
Enter fullscreen mode Exit fullscreen mode

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)