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:
- Using a callback, in reference to closure hell
- Combining the states
- Tracing the error with React Dev Tools on Chrome
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).
CodePudding user response:
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('');
}
};
CodePudding user response:
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) => {....}
CodePudding user response:
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?