0

I have two components. One components renders a "title" input.

The other component renders a "note" input with 2 buttons.

I have the title input values stored in state called "title"

I have the note input value stored in state called "note"

Now i'm trying to get my title and note values in an object like so:

const [completedNote, setCompletedNote] = useState([{ id=1, title: "", note=""}])

//App component

import React, { useState } from "react"
import NoteTitle from "./components/note-title/NoteTitle";

export default function App() {
  const [title, setTitle] = useState("");
  const [note, setNote] = useState("");
  const [completedNote, setCompletedNote] = useState([
    { id: 1, title: "", note: "" },
  ]);

  return (
    <NoteTitle
      title={title}
      setTitle={setTitle}
      note={note}
      setNote={setNote}
    />
  );
}

//Title Component

import React, { useState } from "react";
import Note from "../note/Note";

export default function NoteTitle({ title, setTitle, note, setNote }) {

  return (
    <>
      <div className="note-maker__maincontainer">
        <div className="note-maker__sub-container">
          <div className="note-maker__input-container" ref={wrapperRef}>
            <div className="note-maker__title">
              <input
                id="input_title"
                type="text"
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                placeholder="Title..."
                onClick={() => setIsNoteDisplayed(true)}
              />
            </div>
             <Note note={note} setNote={setNote} /> 
          </div>
        </div>
      </div>
    </>
  );
}

// Note Component

import React from "react";
export default function Note({ note, setNote }) {
  return (
    <>

      <div className="note__container">
        <div className="note-maker__note">
          <input
            id="input_note"
            type="text"
            value={note}
            onChange={(e) => setNote(e.target.value)}
            placeholder="Take a note..."
          />
        </div>

        <div className="note-maker__buttons-container">
          <button className="note-maker__submit-button" type="submit">
            Submit
          </button>
          <button className="note-maker__close-button">Close</button>
        </div>
      </div>
    </>
  );
}

How would I go about doing this? I have tried this but its causing "error: To many renders"

 setCompletedNote((prevState) =>({
    title:{
      ...prevState.title,
      [title]: title,
      note:{
        ...prevState.note,
        [note]: note
      }
    }
  }))

Thanks in advance!

2
  • please post the full code . Your completedNote is an [ ] but what you are trying to set is an object . Commented May 28, 2021 at 15:11
  • I have updated the thread with all my code. Commented May 28, 2021 at 15:19

2 Answers 2

1

If you just want to add a new Completed Note then

Note: Use some library like uuid to generate id and don't do it like below :)

// You have to initiate just an empty array
const [completedNote, setCompletedNote] = useState([]);

// Call this function on submit
const addCompletedNote = () => {
  // TODO: validate note and title are not empty
  
  // Add new object to state
  setCompletedNote((prevState) => [
        ...prevState,
        { id: Date.now(), note: note, title: title }
      ]);


  // Clean up existing state
  setTitle("");
  setNote("");

  // Note: this above clean-up triggers state updates 2 times which is not that good but works :) . 
  // TODO: so try to solve it by combining title, note and completedNote to be a single state object
  // like this => { title: "", note: "", completedNote: [] } 
  // This above change requires a lot of extra changes to work (Try figuring them out :))
}

If you want to update title and note of an existing Completed Note, you need id, newTitle, and newNote values. You update the value of the object that matches the input id.

const updateCompletedNote = (id, newTitle, newNote) => {
 
    setCompletedNote((prevState) => prevState.map(n) => {
      if (n.id === id) { // match the id here
        return {...n, title: newTitle, note: newNote}; // return new object
      }
      return n; // objects that do not match id are returned as it is
     });

}

You can also update just note or just title But you always need id of the object.

Lets say if you want to just update title of the object you need both id and newTitle and return

return {...n, title: newTitle };

instead of

return {...n, title: newTitle, note: newNote};

Sign up to request clarification or add additional context in comments.

8 Comments

I want to be able to add the values from my input boxes into my object. I have the values from the input boxes set to state, just need to put those values in my object. Little confused by this. I posted my full project if this helps.
Your full project code does not use completedNote anywhere. I assume you are trying to build something similar to a todo app. Where you take title and note from user and once they submit you add that to completedNote with auto generated id. But if it is not the case you can comment what exactly is completedNote used for and describe your project a bit more.
yes, that is correct. Basically, when the user hits the submit button I want the values from the inputs to be stored in an array of objects. (Like how google keep works) as of now, completedNote is in my App.js component if you look closely haha I apologize if it’s messy!
Once the submit button is clicked and I have the values from the inputs in contained objects I will map through my object array and display the individual notes below. If you look at google keep you will have a better understanding or what my intentions are
Hey i made some changes to the answer. From what I understand you just need addCompletedNote function. But try adding edit note feature and try to use the updateCompletedNote function and also try to implement delete note as a practice :)
|
0

Your setCompletedNote function is missing the last closing parenthesis )

You should pass in the arrow function enclosed in curly braces to prevent an infinite loop:

setCompletedNote({
  (prevState) => ({
    title: {
      ...prevState.title,
      [title]: title,
      note: {
        ...prevState.note,
        [note]: note
      }
    }
  })
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.