Create a Notes app with React and javascript Localstorage.
Tags: javascript, react, web, beginners
Published: 2022-09-05 20:37:30

A notes app is a crucial tool for recording information that has to be retrieved later.
In this tutorial, we'll create a working notes app with features like note deletion, we'll utilise react hooks to store the notes and  use localstorage to keep our notes even when the browser is closed.

The prerequisites for this project are:

- Knowledge of CSS, Javascript, React.js
- Latest version of Node.js installed

## Getting started
If you have npm and Node.js installed, create a new react app `notes-app`. We'll achieve this using `npx create-react-app`

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pctam6x5z80ywdwh96so.png) 

## Creating our components
First, we make a components folder in the app's src directory which will store our components - `Note`, `Notes` and `Createnote`. Additionally, it will have a CSS folder in which our app's styles will be kept.

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3g1v5marijz4yw57wc5.png)

## Storing necessary data
Both the text that is presently being typed and the list of notes that we currently have must be stores in order for them to be used in the notes application.
To achieve this, in our `Notes.js` file we import `react` and `useState` from react.

```javascript
import React,{useState} from 'react'

```
Then we use the `useState` hook to store our notes array and input text.

```javascript
    const [notes,setNotes]=useState([])
    const [text,setText]=useState('')
```

## Building the basic procedures of the notes app
We will create the functions that will update input text, save and delete a note.

```javascript
    const updateText=(e)=>{
        setText(e.target.value)
    }

    const saveNote=()=>{
        setNotes((prevState)=>[
            ...prevState , {
                key:uuid(),
                id:uuid(),
                text:text,
            }
        ]);
        setText('');
    }

    const deleteNote =(id)=>{
        const filteredNotes=notes.filter((note)=>{return note.id !== id});
        setNotes(filteredNotes);
    }
```
In the above code

- `updateText` function takes the user's keyboard input and stores it in the text variable using the `useState` hook.

- `saveNote` function creates a new object and adds it to the existing notes array. We create a key and an id for the object in order to construct arrays in React and delete a note respectively.
 They are generated with [uuid v4](https://www.npmjs.com/package/uuidv4). You can install it as follows:

```
npm install uuidv4
```
And use it as follows:

```javascript
import { v4 as uuid } from "uuid";
```
The text parameter will be assigned to the value of `text`, that is our desired text cotent for the note. The value of `text` was then set to empty in order to create new content for our future note.

- `deleteNote` function takes in the id of our note as a parameter, uses the filter method to return all notes except for that which it's id has been passed to the function.

## Constructing the body of our notes app
We want the structure of our notes app to first display all saved notes, then display an input field to create a new note.

```jsx
 return(
        <div className='Notes'>
            {notes.map((note)=>(
            <Note deleteNote={deleteNote} id={note.id} text={note.text}/>
            ))}
            <Createnote updateText={updateText} saveNote={saveNote} inputText={text} />
        </div>
    )
```
First of all, we call a map method on the `notes` array, the note is passed `deleteNote`, `id`, and `text` props which will be utilised to make it perform it's functions. The `id` and `text` prop are passed to the value of the note's id key and text key respectively.  
Then, we include our `Createnote` component and pass the necessary functions to the `updateText` and `saveNote` props. `text` is passed to the `inputText` prop and is used in the `Createnote` component to update the value of our textarea.

## Preparing the `Note` component
After we created the notes app's general framework, the next task is to head over to `Note.js` and develop the `Note` component by typing the following:

```jsx
import React from "react"


function Note({id,deleteNote,text}){
    return(
        <div className="note">
            <div className="note-body">{text}</div>
            <div className="note-footer">
                <button onClick={()=> deleteNote(id)}>Delete</button>
            </div>
        </div>
    )
}

export default Note
```
 The `note-body` div contains the content of the note therefore the value of `text` is passed to it. Remember that this is the content that is stored in the note object when a new note is saved.
The `note-footer` div contains the delete button  that performs a function when clicked. The function calls our `deleteNote` function located in `Notes.js` with `id` passed as a parameter.

## Building our `Createnote` component
We have successfully completed the structure of our note, but we still need a textarea to collect the user's input and store it as a new note. In `Createnote.js`, we add the following:

```jsx
import React from 'react'

function Createnote({updateText,saveNote,inputText}){

    return (
        <div className='note' >
            <textarea onChange={updateText} maxLength={100} placeholder='Type Here...' value={inputText} ></textarea>
            <div className='note-footer'>
                <button onClick={saveNote}>Save note</button>
            </div>
        </div>
    )
}


export default Createnote
```
All text is inputed into a textarea with a maximum length of 100 characters, the value is also set to `inputText` so that the textarea can be cleared once we save the note. We add `onChange` attribute to the textarea in order to update the `text` in our `Notes` component. The `note-footer` div contains the delete button  that perform the `saveNote` function when clicked.
Next, we include a counter to let the user know how many characters are still available for input.

```javascript
    const maxLength=100;
    const counter=maxLength-inputText.length;
    return (
        <div className='note' >
            <textarea onChange={updateText} maxLength={100} placeholder='Type Here...' value={inputText} ></textarea>
            <div className='note-footer'>
                <span>{counter}</span>
                <button onClick={saveNote}>Save note</button>
            </div>
        </div>
    )
```

## Storing notes with `localstorage`
Our notes app is complete but we don't what to lose our saved notes when the browser is closed, we prevent this by using javascript `localstorage` and useEffect hook. `notes` is included in the square bracket of the useEffect function to make sure our notes are saved upon every render in which `notes` is updated.

```javascript
    useEffect(()=>{localStorage.setItem('Notes',JSON.stringify(notes))},[notes]);

    useEffect(()=>{const data=JSON.parse(localStorage.getItem('Notes'));setNotes(data)},[]);
    
 ```
useEffect has to be imported from react for this to work.

```javascript
import React,{useState,useEffect} from 'react'
```
 

## Linking our components
We've created our `Note` and `Createnote` conponents, next we import them in `Notes.js` in order to make our note app fully functional.

```javascript
import Note from './Note'
import Createnote from './Createnote'
import Note from './Note'
```
Our app won't display yet because we still haven't imported the `Notes` component into `App.js`. We complete the body of our notes app with the following:

```javascript
import React from 'react'
import './App.css';
import Notes from './components/Notes.js'

function App() {
  
  return (
    <div className="App">
      <h1>Notes</h1>
      <Notes />
    </div>
  );
}

export default App;

```

## Styling our app
The styles for notes app will be stored in our `notes.css` file located in our css folder.

```css
.note{
    height: 250px;
    margin-right: 10px;
    border-radius: 35px;
    width: 30%;
    position: relative;
    display: inline-block;
    vertical-align: top;
    border: 2px solid black;
    margin-bottom: 20px;
    background-color: #f9ce69;
}
textarea{
    outline: none;
    resize: none;
    border: none;
    background: transparent;
    box-sizing: border-box;
    max-width: 100%;
    min-width: 100%;
    max-height: 82%;
    min-height: 82%;
    font-size: 25px;
    line-height: 35px;
    padding: 10px 0 0 10px;
}

.note-body{
    line-height: 35px;
    padding: 10px 0 0 10px;
    font-size: 25px;
    height: 82%;
}


button{
    background-color: #4741a6;
    padding: 10px 15px;
    float: right;
    border: none;
    border-radius: 15px;
    font-size: 15px;
    color: white;

    position: absolute;
    bottom: 10px;
    right: 10px;
}
span{
    color: red;
    padding-left: 10px;
    font-weight: 600;
}


```

## Conclusion
This article demonstrated how to build a straightforward notes app which saves notes even if the browser is lost. Additionally, it explains how to use react hooks to store items and carry out specific tasks automatically.
The Github repository is located [here](https://github.com/Gbadeboife/React-notes-app) and a live demo of the site is hosted on [vercel](https://react-notes-app-xi-steel.vercel.app/).