Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Modify object property in setState using unique id?

I’m trying to update an object property within an array based on a unique id property.
For example I have this in state:

const [speakers, setSpeakers] = useState([
    {
      id: nanoid(),
      name: "",
      title: "",
      position: "",
      description: ""
    }
  ])

I have a card, with a form in it, 3 text inputs, 1 textarea input, and the last piece is a field where I can upload a photo, crop it, get the base64 string, now I want to save this value in a photo property, inside the correct form. I created a "Add new speaker" button, and wrote some code that adds a new card (with the form), and also a delete button, which removes the specific card. All of that is working great, the whole point of my issue is that, after I crop the image, I want my state to look like this:

const [speakers, setSpeakers] = useState([
    {
      id: nanoid(),
      name: "",
      title: "",
      position: "",
      description: "",
      photo: "base64 string here"
    }
  ])

I know this is wrong, but I’m using the index, instead of the unique id, but this is what I have so far, that isn’t working.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const getBase64Image = data => {
    imageRef.current.src = data
    let index = imageRef.current.id
    
    setSpeakers([
      {
        // object that we want to update
        ...speakers[index],
        photo: data // update the value of specific key
      }
    ])
  }

Just know that the data, is the base64 string. It works on the first try, but then if I add a second speaker/card/form, it removes the first object, and acts odd. Just to be clear, in the end, I should have/want this:

const [speakers, setSpeakers] = useState([
    {
      id: "123",
      name: "Bob",
      title: "",
      position: "",
      description: "",
      photo: "base64 string here"
    },
    {
      id: "456",
      name: "Peter",
      title: "",
      position: "",
      description: "",
      photo: "new base64 string here"
    },
    {
      id: "789",
      name: "Tim",
      title: "",
      position: "",
      description: "",
      photo: "new new base64 string here"
    },
  ])

Coming from Vue, new to React, thank you!!

>Solution :

Your current setState is only returning an array with one element. You want to find the one with id === index, I think, and then add the photo prop to it, and leave the other array entries as they are. You need to create a whole new object because of React’s immutable rules. So,

setSpeakers(curSpeakers => curSpeakers.map(s => 
  s.id === index ? {...s, photo: data} : s
));
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading