I have a code where I output images dynamically. And in the state I have an array with objects {url: null, name: null}
.
When I load an image, I get the image name
fine, but not url
. And i can’t understand why. Here is the complete code:
const [UploadLogos, setUploadLogos] = useState([
{ url: null, name: null}
])
const setParam = (Param, newParam, i) => {
setUploadLogos([
...UploadLogos.slice(0, i),
{ ...UploadLogos[i], [Param]: newParam },
...UploadLogos.slice(i + 1),
])
}
{
UploadLogos.map((Logo, i) => (
<ImageUpload
key={i}
Image={Logo.url}
setImage={(prev) => setParam("url", prev, i)}
Name={Logo.name}
setName={(prev) => setParam("name", prev, i)}
/>
))
}
ImageUpload.jsx
export function ImageUpload({Image, setImage, Name, setName}) {
return (
<>
<input
type="file" accept="image/png" onChange={event => {
const ImageURL = URL.createObjectURL(event.target.files[0])
const ImageName = event.target.files[0]['name']
setImage(ImageURL)
setName(ImageName)
console.log(ImageURL) ===> blob:http://localhost......
console.log(Image) ===> null
console.log(ImageName) ===> simpleImage.png
console.log(Name) ===> simpleImage.png
}}
/>
</>
)
}
In the console in the component I showed what I was getting. And Image
is always null
, although, I put it in setImage(ImageURL)
.
What is the error?
4
Answers
Maybe share the console.log result of the entire UploadLogos array from a
useEffect
and see if that’s right.One thing about using an array index as the key when you map is that it doesn’t track changes in the array when you do stuff like re-order or slice etc. because the index doesn’t change
key={i}
Here’s why:
error: Do not use Array index in keys
Try using
key={Logo.url}
and see if that workswhen you call setImage(), the state is not updated immidiately. so, when you reach
console.log(Image)
, it is still printing the previous value and not the new value.you can see if the correct value is set for image, in a useEffect like this:
The error you seeing is because you are setting a same state variable without using functional update feature of useState hook.
The code that causes the issue:
And
The core of the issue is that react’s setter from useState hook is not updating the variable itself immediately, updates will be available on next render only. And because of that – setImage results are completely ignored due to setName overwrites the data that was set previously, because
UploadLogos
variable does not have any data set by setImage yet, in the current render.The fix:
Your code is good but here is one issue while setting the state.
Here your state is not getting preserved that’s why you were getting it as null as name is overwriting the state.
SO this is how you can preserve the state with minor change:-