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!!
2
Answers
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,
The way the code is written it will replace the entire contents of the array with the one entry that is being updated when
setState
is called. You will have to update the array in place ( shallow copy ) based on the index and then update the values in state.Existing code
Updated Code