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.
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
));