Google Keep Lite - Building Google Keep clone using reactjs
Tags: react, webdev, css, javascript
Published: 2021-02-28 13:49:39

This blog will explain how to create a Google Keep clone using reactjs.

#### Step 1
### Building input to take note

This input show open up on click as in Google Keep. For this, state has *visible* set as *false* and on clicking anywhere on the input, visible will be set as *true* and the input will open up. The same visible will be set *false* on clicking the close button.
![input](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j1imqdoomcq1r6xd2r5s.PNG)
 
####Step2
### Taking notes

For taking notes, a controlled input is used. It will take input from user. The state has a propety *note*. The *title* and *input* of note will be updated using handleChangeNote function
![takenote](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3455lju1pptmq1df6pq4.PNG)
 
Then, on clicking the close button this note will be appended to notes_list of state using unshift method.
![takenote1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7mojfcnz4kjzrtgv2ht.PNG)
If there is no user input provided, then the close button will only set visible as *false* close the input.

####Step 3
###Displaying notes

To display notes, **react-masonry-css** is used. It is a masonry component powered by CSS built specifically for React projects.

**Why react-masonry-css ?**
I tried using normal layout to display all the notes with height set as auto for each note. But this concept had an issue. Each row of notes took height of the longest note. Hence, to get Masonary look, I used react-masonry-css.

**Installation**
To install react-masonry-css, run the following command in your command propmt.
![mason](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmlb8wuv9jiakmlp0w2r.PNG)

The breakpointCols is used to define the number of columns required in the layout.
![mason1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rhw0myrn7i30rgbms0g.PNG)

To display each note from the notes_list, I've used filter and map method. 

####Step 4
### Deleting note
To delete a note, we need to remove the note from the array.
For this, I used a function *removeFromNotes*. This function is called with note index and notes_list is updated & returned with all the notes except for the one with the mentioned note index.
![delet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ocjrtwbd7f0lcwvu50gy.PNG)

####Step 5
###Pinning note
On clicking the pin button, a function will run which will have note id as parameter. The state has a property *pinned_id* set as *null*. This function will set pinned_id as the note id.
![pin](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5x18z9wld5lwm7t92ss8.PNG)
Therefore, it will be check if pinned_id is null or not. If not, the pinned note will be displayed above all notes.
![pin1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ri0xwyx6q5hrro150by6.PNG)

For deleting a note from pinned note, I just removed the note from notes_list and set the pinned-id as null as shown above in removeFromNotes.

####Step 6 
###Searching a note

When note to be searched is put in search bar, the change will be updated in the *search* property of state. Search is initially set to null. Then, the *serach_list* of state will be updated with all the notes which include what's been searched. This is done using *includes* method on *title* as well as *input* of note.
![search](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/frltm7cdktflpeltja17.PNG)

To display the searched note, a ternary operator is used to check if *search* of state is null or not. If not null, the searched note is displayed.
![search1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4guzoptvvuccm6m3k91j.PNG)

####Step 7
###Editing note

When edit button is clicked, a function will run which will set a boolean *showPopUp* to true from false, the popup_id will be set to the note id, and *edited_note* is updated with the note. Hence, the popup will show which will have z-index 1.
![edit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5mxbtra4p1ncdjibawtg.PNG)

Any change in note will be handled with handleChangeNote function. And the close button will run a function which will update notes_list with the edited note.

####Step 8
###Trash bin

Trash Bin will be a different component. All the things mentioned above will go in Home component. To go to trash from home without refreshing page, **react-router** is used. Firstly, react-router-dom should be installed by running the installation command ( npm install react-router-dom ) in command prompt.

![router](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vivh75wxtaqrir60fdat.PNG)
 
When delete button is clicked, the note id will be passed as parameter for the function *removeFromNotes*. The *deleted_note* of state will be updated with the note to be deleted. And this deleted_note will be added to *trash_list* of state using unshift method.
![trash](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1u67rnxm7znny1s11q46.PNG)

####Step 9
### Deleting Forever

The notes in trash bin is having a button to delete it forever. To delete the note forever, the *trash_list* should be updated and the notes, having id other than the id that was passed, should be returned.

![trash1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/um27g9pqi48ode69f3xa.PNG)
 
####Step 10
###Persisting data on browser

To persist the data on the browser, localstorage API is used.
Firstly, while running *addToNotes*, the notes added are passed to localstorage using setItem.
![ls](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u38xhiyt1etpdspfy1jm.PNG)

Then, on deleting the note, the localstorage is updated. 
![ls1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h69iyz1ba9jtk68j2h0t.PNG)

The notes stored will not be lost on a refresh. As soon as the App component will mount, the notes on home page and in trash will be shown.
![ls4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v7xm55jis2zvuanookl8.PNG)
 

**The screenshots provided below will you a glimpse of how the app looks.**

**Homepage** 
![2021-02-28](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g97lec6lvjwtgkphm0ua.png)

**Taking note**
![2021-02-28 (1)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2b7qm893h5zdb9rcjr17.png)

**Searching note**
![2021-02-28 (2)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gdx9ekr4qx66augjr7m6.png)

**Pin note**
![2021-02-28 (3)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jv4fgq3nlm5jgjes30cg.png)

**Edit note**
![2021-02-28 (4)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0cl7er7bsbbvztn59j5m.png)

**Trash bin**
![2021-02-28 (6)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbz54kc8w8gjw15z8piy.png)
 

**Live Demo**: http://bit.ly/2O9Fm36
**Source Code**: https://github.com/shambhavijs/gkeep-lite