JSFiddle - React, Tailwind, and code Playground

JavaScript

const noteClassName = 'note';
const noteContainerClassName = 'note_container';
const emptyText = '[empty]';

class StorageNotes {
  constructor(name) {
    this.name = name;
    this.data = (this.load()) ? this.load() : ['']
  }

  add(text) {
    this.data.unshift(text);
    this.save();
  }

  set(i, text) {
    this.data[i] = text;
    this.save();
  }

  remove(i) {
    this.data.splice(i, 1);
    this.save();
  }
  save() {
    window.localStorage.setItem(`__notes_storage_${this.name}`, JSON.stringify(this.data));
  }
  load() {
    return JSON.parse(window.localStorage.getItem(`__notes_storage_${this.name}`));
  }
}

class Notes extends StorageNotes {
  constructor(name, parentElem = document.body) {
    super(name);
    this.notes = null;
    this.parentElem = parentElem;
    this.wrapper = this.setWrapper();
    this.renderCreateButton();
    this.renderNotes();
  }

  setWrapper() {
    const wrapper = document.createElement('div');
    return this.parentElem.appendChild(wrapper);
  }

  renderNotes() {
    if (this.notes) {
      this.notes.parentNode.removeChild(this.notes);
    }
    this.notes = document.createElement('div');
    this.notes.classList.add(noteContainerClassName);
    this.wrapper.appendChild(this.notes);
    this.data.forEach(this.renderNote.bind(this, this.notes));
  }

  addNote() {
    this.add('');
    this.renderNotes();
  }

  removeNote(i) {
    this.remove(i);
    this.renderNotes();
  }

  saveNote(i, e) {
    this.set(i, e.currentTarget.previousSibling.value);
    this.renderNotes();
  }

  renderNote(parent, text, i) {

    const createNote = () => {
      const note = document.createElement('div');
      note.classList.add(noteClassName);
      parent.appendChild(note);
      return note
    };
    const createEditElem = () => {
      const editEl = document.createElement('div');
      editEl.style.display = 'none';
      return editEl;
    };
    const createTextEl = () => {
      const textEl =...