This project is a simple CRUD (Create, Read, Update, Delete) application built with React.js, using Json-Server as a mock REST API and ReactBootstrap for the user interface. The application allows users to create, read, update, and delete posts.
The project is structured into several components and a custom hook:
- App: The root component that orchestrates other components and manages the state related to the posts.
- ShowPosts: Displays a list of posts and allows the user to delete or edit a post.
- CreatePost: Provides a form for creating new posts.
- EditPost: Allows the user to edit a selected post.
- usePosts: A custom hook that fetches posts from the server and provides a way to trigger a refetch of the posts.
The project also includes a constants file for storing constant values and a package.json
file for managing dependencies and scripts.
The project uses several libraries and tools, including React, Axios for HTTP requests, Bootstrap for styling, Json-Server for creating a fake REST API, and TypeScript for static type checking. The code is linted using ESLint, and the project is built and served using Vite.
- run
yarn
to install all the dependencies - run
yarn backend
to start the json-server - run
yarn dev
to start the react app
The backend is a simple json-server with a db.json file that contains the data.
All the data is stored in the db.json file.
It acts like a REST API and provides the data for the frontend.
The Json Server spins up on port 3333.
The posts
endpoint is available and provides the following methods:
- GET /posts
- GET /posts/:id
- POST /posts
- PUT /posts/:id
- DELETE /posts/:id
The frontend is built with React.js and uses ReactBootstrap for the UI. The app utilises the json-server as a REST API to perform CRUD operations. The components:
The App
component is the root component of the application. It orchestrates the other components and manages the state related to the posts.
The App
component imports several hooks and components:
useState
fromreact
for managing local state.CreatePost
,EditPost
, andShowPosts
components for creating, editing, and displaying posts respectively.usePosts
custom hook for fetching posts from the server.
The App
component maintains two pieces of state:
posts
andtriggerRefetch
from theusePosts
hook.posts
is an array of posts fetched from the server, andtriggerRefetch
is a function to refetch the posts.postToUpdateId
is a state variable that holds the ID of the post to be updated. It's initiallyundefined
.
The App
component defines one function:
onEditComplete
setspostToUpdateId
back toundefined
and triggers a refetch of the posts. This function is called when the editing of a post is completed.
The App
component renders a div
that contains the CreatePost
, ShowPosts
, and EditPost
components.
CreatePost
is passed thetriggerRefetch
function as a prop so it can trigger a refetch after creating a new post.ShowPosts
is passed theposts
array, thetriggerRefetch
function, and thesetPostToUpdateId
function as props. It displays the posts and allows the user to choose a post to edit.EditPost
is passed thepostToUpdateId
and theonEditComplete
function as props. It allows the user to edit the selected post and triggers theonEditComplete
function when the editing is done.
The ShowPosts
component is responsible for displaying a list of posts. It uses the axios
library to send HTTP requests, and Bootstrap for styling.
The ShowPosts
component accepts three props:
posts
: An array of posts to be displayed.triggerRefetch
: A function that triggers a refetch of the posts. This function is called after a post is successfully deleted.setPostToUpdateId
: A function that sets the ID of the post to be updated. This function is called when the user clicks the "Edit" button of a post.
The ShowPosts
component defines two functions:
-
onDeletePost
: This function is called when the user clicks the "Delete" button of a post. It sends a DELETE request to the server to delete the post, and triggers a refetch of the posts. -
onEditPost
: This function is called when the user clicks the "Edit" button of a post. It sets the ID of the post to be updated.
The ShowPosts
component renders an unordered list of Bootstrap Card
components. Each Card
contains a CardBody
that displays the title and content of a post, and "Delete" and "Edit" buttons. The onDeletePost
function is attached to the onClick
event of the "Delete" button, and the onEditPost
function is attached to the onClick
event of the "Edit" button.
The CreatePost
component is a form for creating new posts. It uses the axios
library to send HTTP requests, and Bootstrap for styling.
The CreatePost
component accepts one prop:
triggerRefetch
: A function that triggers a refetch of the posts. This function is called after a new post is successfully created.
The CreatePost
component maintains one piece of state:
newPost
: An object representing the new post to be created. It hastitle
andcontent
properties, both of which are initially empty strings.
The CreatePost
component defines two functions:
-
onInput
: This function is called when the user types into the title or content input fields. It updates thenewPost
state with the new input. -
onCreatePost
: This function is called when the user clicks the "Create New Post" button. It first checks if thenewPost
object is valid (i.e., both the title and content are non-empty). If it's valid, it sends a POST request to the server to create the new post, resets thenewPost
state, and triggers a refetch of the posts.
The CreatePost
component renders a Bootstrap Card
that contains a CardBody
. Inside the CardBody
, there are two input fields for the title and content of the new post, and a "Create New Post" button. The onInput
function is attached to the onChange
event of the input fields, and the onCreatePost
function is attached to the onClick
event of the button.
The EditPost
component is responsible for editing a post. It uses the axios
library to send HTTP requests, and Bootstrap for styling.
The EditPost
component accepts two props:
postId
: The ID of the post to be edited.onEditComplete
: A function that is called when the editing of a post is completed.
The EditPost
component maintains one piece of state:
postToUpdate
: An object representing the post to be updated. It's initiallyundefined
.
The EditPost
component defines four functions:
-
fetchPost
: This function is called when thepostId
prop changes. It sends a GET request to the server to fetch the post to be updated, and sets thepostToUpdate
state with the fetched post. -
handleHide
: This function is called when the modal is closed. It triggers theonEditComplete
function. -
onInput
: This function is called when the user types into the title or content input fields. It updates thepostToUpdate
state with the new input. -
onSave
: This function is called when the user clicks the "Save changes" button. It sends a PUT request to the server to update the post, resets thepostToUpdate
state, and triggers theonEditComplete
function.
The EditPost
component renders a Bootstrap Modal
that contains a Modal.Dialog
. Inside the Modal.Dialog
, there are input fields for the title and content of the post, and "Close" and "Save changes" buttons. The onInput
function is attached to the onChange
event of the input fields, the handleHide
function is attached to the onClick
event of the "Close" button, and the onSave
function is attached to the onClick
event of the "Save changes" button.
The usePosts
hook is responsible for fetching posts from the server and providing a way to trigger a refetch of the posts.
The usePosts
hook maintains two pieces of state:
posts
: An array of posts fetched from the server. It's initially an empty array.refetch
: A number that is incremented each time a refetch of the posts is triggered. It's initially0
.
The usePosts
hook defines two functions:
-
triggerRefetch
: This function increments therefetch
state, which triggers a refetch of the posts. -
fetchPosts
: This function is called when theusePosts
hook is mounted and each time therefetch
state changes. It sends a GET request to the server to fetch the posts, and sets theposts
state with the fetched posts.
The usePosts
hook returns an object with two properties:
posts
: The array of posts fetched from the server.triggerRefetch
: The function to trigger a refetch of the posts.
The constants
file is responsible for storing constant values that are used throughout the application.
The JSON_SERVER_BASE_URL
constant is the base URL of the JSON server from which the application fetches and updates posts. It's set to 'http://localhost:3333'
.
The package.json
file is responsible for managing the dependencies and scripts for the project.
The project uses several dependencies:
react
andreact-dom
for building the user interface.axios
for making HTTP requests.bootstrap
andreact-bootstrap
for styling the components.json-server
for creating a fake REST API for development purposes.@popperjs/core
andsass
for additional styling and positioning capabilities.@types/node
,@types/react
, and@types/react-dom
for TypeScript type definitions.global
for global variables.
The project uses several development dependencies:
typescript
for using TypeScript.eslint
,@typescript-eslint/eslint-plugin
,@typescript-eslint/parser
,eslint-plugin-react-hooks
, andeslint-plugin-react-refresh
for linting the code.@vitejs/plugin-react
andvite
for a faster and leaner development experience.
The project defines several scripts for development, building, and linting:
dev
for starting the development server.backend
for starting the JSON server.build
for building the project.lint
for linting the code.preview
for previewing the production build.