1

I'm trying to implement a notes app with a title property. I, previously, had the notes app working w/o adding-a-title functionality but now that I've integrated it, I have the following issue: the return of the textarea element (the note text itself) is undefined while the return of the input element (the note title) returns the valid title.

The code below is, I'm certain, the component where the error stems from - the component being AddNote.

What I've tried thus far:

What I haven't tried:

import React, { useState } from 'react';

const AddNote = ({ handleAddNote }) => {
  const [noteTitle, setNoteTitle] = useState('');
  const [noteText, setNoteText] = useState('');

  const handleSaveClick = () => {
    if ((noteText.trim().length > 0) && (noteTitle.trim().length > 0)) {
      handleAddNote(noteText);
      setNoteText('');

      handleAddNote(noteTitle);
      setNoteTitle('');
    }
  };

  return (
    <div className='note new'>
      <div className="toolbar">
        <button
          className='add-delete-icon'
          onClick={handleSaveClick}
        >+</button>
        <input
          type="text"
          className="note-title"
          placeholder="Add a title..."
          value={noteTitle}
          onChange={
            event => setNoteTitle(event.target.value)
          }
          autoFocus
        />
      </div>
      <textarea
        className="note-text"
        placeholder="Add an idea..."
        value={noteText}
        onChange={
          event => setNoteText(event.target.value)
        }
      ></textarea>
    </div>
  );
};

export default AddNote;

Am I doing something incorrectly here, particularly with using multiple instances of useState, i.e., this idea of "batching" the 'setState' calls? Or rather, does the issue fall within the handleSaveClick anonymous function?

The dependent components - meaning, the one's that refer to adding-a-title-functionality - are the Note component (Pastebin), the NoteList component (Pastebin), and notable the Home component (Pastebin).

  • The code you're providing here seems to work - that is `handleAddNote` gets both values for the note text and title. When you say _"the return of the textarea element (the note text itself) is undefined"_, where are you checking the note text that makes you say it's `undefined`? – Nick Parsons Nov 09 '21 at 09:04
  • Weird to call handleAddNote with both the title and the text. How do you differentiate between them in the callback? – jperl Nov 09 '21 at 09:08
  • Have you tried to consolelog before call setNoteText? Is it undefined there? When is it undefined? Please, show us all relevant code. – jperl Nov 09 '21 at 09:11

3 Answers3

2

Looking at the code, you should call handleAddNote like this

if ((noteText.trim().length > 0) && (noteTitle.trim().length > 0)) {
    handleAddNote(noteTitle, noteText);
    setNoteText('');
    setNoteTitle('');
  }

handleAddNote is addNote func in Home.jsx. addNote take title and text as arguments

const addNote = (title, text) => {....}
kiranvj
  • 32,342
  • 7
  • 71
  • 76
1

With your updates, you've shown that you've defined the following function in your Home component:

const addNote = (title, text) => {
  const date = new Date();
  const options = { ... };

  const newNote = {
    id: nanoid(),
    title: title, // <--- here
    text: text, // <--- here
    date: date.toLocaleDateString(undefined, options)
  };

  const newNotes = [...notes, newNote];
  setNotes(newNotes);
};

This addNote() function expects two arguments to be passed to it, a title and text which is then used in your newNote object (see <--- here comments above). You're then passing this addNote function as a prop to NoteList:

<NotesList
  notes={notes}
  handleAddNote={addNote}
  handleDeleteNote={deleteNote}
/>

And then again, inside of NoteList, you're passing handleAddNote (which is a reference to your addNote function) to AddNote:

<AddNote handleAddNote={handleAddNote} />

As a result, when you call handleAddNote() inside of your AddNote component, you're calling the addNote() function defined in Home, which needs to be passed both your title and text in the one call like so:

const handleSaveClick = () => {
  if ((noteText.trim().length > 0) && (noteTitle.trim().length > 0)) {
    handleAddNote(noteTitle, noteText);
    setNoteText('');
    setNoteTitle('');
  }
};
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
  • @duke no worries. Yes, that's right, the order of the arguments that you call `handleAddNote()` must align/match up with the order of the parameters of the function definition, so for `(title, text) => `, the value you want to be used for `title` is passed to `hanldeAddNote()` first and then the value for `text`) – Nick Parsons Nov 09 '21 at 09:26
0

I would say that the problem is here:

const handleSaveClick = () => {
  if ((noteText.trim().length > 0) && (noteTitle.trim().length > 0)) {
    handleAddNote(noteText);
    setNoteText('');

    handleAddNote(noteTitle);
    setNoteTitle('');
  }
};

You're calling handleAddNote() twice. What does this function look like?

Mikaels Slava
  • 186
  • 2
  • 8