28
loading...
This website collects cookies to deliver better user experience
npm
and installed necessary dependenciesMongoDB
databasenode.js
and express.js
schema
to define a TODO
create
, read
, update
and delete
todocreate-react-app
.
└── mern-todo
├── server
└── client
create-react-app
in the client
folder. Run the following command from the terminal but make sure you are in the client
folder.npx create-react-app .
.
in the above command refers to the current folder
. This will install our react app in the current folder instead of installing the app in a different folder.npm i node-sass axios react-router-dom
node-sass
: allows using sass
instead of css
axios
: to make api calls to the backend
react-router-dom
: for routing between pagesclient
's folders package.json
should look something like this.{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"axios": "^0.21.1",
"node-sass": "^6.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": ["react-app", "react-app/jest"]
},
"browserslist": {
"production": [">0.2%", "not dead", "not op_mini all"],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
logo.svg
App.js
App.js
<header className="App-header">
<img src="{logo}" className="App-logo" alt="logo" />
<p>Edit <code>src/App.js</code> and save to reload.</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<header>Hello, World!</header>
Delete the index.css
file and remove the corresponding import from index.js
Rename the App.css
file to App.scss
and change the corresponding import at App.js
import "./App.scss" //updated
Run npm start
. Open http://localhost:3000
and it should display Hello, World!
Copy and paste the styles from here and paste it in the App.scss
file.
.
├── node_modules
├── public
├── src <---------- we are here
│ ├── App.js
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
components
folder inside the src
folder and add the following filescreateTodo.jsx
showTodoList.jsx
updateTodo.jsx
.
├── node_modules
├── public
├── src
│ ├── components
│ │ ├── createTodo.jsx
│ │ ├── showTodoList.jsx
│ │ └── updateTodo.jsx
│ ├── App.js
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
.
├── node_modules
├── public
├── src
│ ├── components
│ │ ├── createTodo.jsx
│ │ ├── showTodoList.jsx <-- we are here
│ │ └── updateTodo.jsx
│ ├── App.js
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
ShowTodoList
component, to read all the documents that we created in the previous part while testing the backend application.useState
and useEffect
hooks from react
axios
from axios
ShowTodoList
function component will have a state todo
, we will fetch the documents from the database and store it in the state todo
.axios
to send a GET
request to the backend to fetch the document. Upon receiving the data we will store the data in todo
using setTodo
and log the data. If we receive an error we'll log that too.useEffect
hook, since we want the data to load when the page loads.TodoCard
component to display the contents of the todo
. We will use map
to iterate over todo
and pass the contents to TodoCard
which will display the contents of each todo document.showTodoList.jsx
file should look something like thisShowTodoList
component in the App.js
fileApp.js
file should look something like thisserver
that we built in part-1
npm run dev
client
side applicationnpm start
http://localhost:3000
in your browser and it should display all the todo documents that was fetched from the database..
├── node_modules
├── public
├── src
│ ├── components
│ │ ├── createTodo.jsx <-- we are here
│ │ ├── showTodoList.jsx
│ │ └── updateTodo.jsx
│ ├── App.js
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
POST
request to our server
using axios.useState
hook react
Link
from react-router-dom
handleChange
that will get the input datahandleSubmit
that will send the POST
request to the server
data
using useState
hook with the following json
{
"title": "",
"description": ""
}
handleChange
method we will update the data
when the input changes. We will call the setData()
and declare a arrow function inside that will copy the contents of the previous data if any exists. In this e.target.name
will be the name of the input element that will have either title
or description
.handleSubmit
method,e.preventDefault()
to prevent the page from reloading when the submit button is clicked.POST
request to the server with the data. If the data has been sent successfully to the server then reset the state data
.
├── node_modules
├── public
├── src
│ ├── components
│ │ ├── createTodo.jsx
│ │ ├── showTodoList.jsx
│ │ └── updateTodo.jsx
│ ├── App.js <-------------- we are here
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
CreateTodo
component we need to update App.js
file.BrowserRouter
and Route
from react-router-dom
CreateTodo
component from components/createTodo
Route
for home page /
and pass the ShowTodoList
componentRoute
for creating a new todo /create-todo
Route
s inside of the BrowserRouter
App.js
file should look something like thishttp://localhost:3000/create-todo
you can type this in your browser to check the CreateTodo
component..
├── node_modules
├── public
├── src
│ ├── components
│ │ ├── createTodo.jsx
│ │ ├── showTodoList.jsx <-- we are here
│ │ └── updateTodo.jsx
│ ├── App.js
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
Link
from react-router-dom
button
inside of Link
tagShowTodoComponent
will look something like this..
├── node_modules
├── public
├── src
│ ├── components
│ │ ├── createTodo.jsx
│ │ ├── showTodoList.jsx
│ │ └── updateTodo.jsx <-- we are here
│ ├── App.js
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
useState
from react
axios
from axios
UpdateTodo
component will have 3 propsupdateTodo.jsx
file may look something like this..
├── node_modules
├── public
├── src
│ ├── components
│ │ ├── createTodo.jsx
│ │ ├── showTodoList.jsx <-- we are here
│ │ └── updateTodo.jsx
│ ├── App.js
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
showTodoList.jsx
handleDelete
that will send a DELETE
request to the server. This function will need the _id
of the document to delete the document from the database. It will also update the array todo
with the filtered array.handleDelete
method as a prop to TodoCard
TodoCard
component to have the parameter handleDelete
onClick
event for the button delete
and pass the handleDelete
method.
├── node_modules
├── public
├── src
│ ├── components
│ │ ├── createTodo.jsx
│ │ ├── showTodoList.jsx
│ │ └── updateTodo.jsx <-- we are here
│ ├── App.js
│ ├── App.scss
│ ├── App.test.js
│ ├── index.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
└── yarn.lock
showTodoList.jsx
UpdateTodo
component from updateTodo.jsx
open
using the useState
hook with the default value of false
. The value of open
will be either true
or false
. We will conditionally render the UpdateTodo
component. If the edit
button is clicked on any one of the todo then we will set open
to true
when the UpdateTodo
component will be rendered.id
using the useState
hook. The _id
of the todo document to be updated will be stored. It will be passed as a prop to UpdateTodo
component.update
using the useState
hook. This will be used to fetch all the todo documents from the database. Each time a todo document has been updated then update
will change between true
and false
handleEdit
. It will update the state id
with the _id
of the document and update the state of open
to true
. The UpdateTodo
component will be rendered.handleUpdate
. This will invert the state of update
if the todo has been updated by the user. Inverting the state will cause the useEffect
hook to update the todo
array.handleClose
. We need this to close the UpdateTodo
component. This will set id
to an empty string and set open
to false
.TodoCard
componenthandleEdit
function to the TodoCard
component.handleEdit
prop to the edit
button.part-2
in GitHub