I have a list of images that render on page load via a map function. I want to be able to select one or more images, and highlight them. Additionally, the selected images' titles will display at the top of the page. The issue I'm running in to is that the list seems to rerender every time I select an image. Here is the component:
export default function App() {
const [images, setImages] = React.useState<Image[]>([]);
const [selected, setSelected] = React.useState<boolean>(false);
const [imageTitles, setImageTitles] = React.useState<string[]>([]);
const handleImageSelection = (title: string, index: number) => {
setSelected(!selected);
const imageExists = imageTitles.indexOf(title) !== -1
if (!imageExists) {
setImageTitles([...imageTitles, title]);
} else {
setImageTitles(imageTitles.filter(str => str !== title));
}
}
return (
<div>
{console.log(images)} // The images array renders every time
<div>{imageTitles.map(title => <p>{title}</p>)}</div>
<section className="images">{
images.map(({ title, image}, index) =>
<img
style={{
marginBottom: 4,
border: imageTitles.indexOf(title) !== -1 ?
"4px solid blue" : "", // A selected image is highlighted
borderRadius: 16
}}
src={image}
alt={image}
onClick={() => handleImageSelection(title, index)}
/>
)
}</section>
</div>
);
}
I'm wondering if it's because I am changing the size of the imageTitles array (and hence, the index values) every time an image is selected/unselected.
I also tried useCallback like so:
const handleImageSelection = React.useCallback((title: string, index: number) => {
setSelected(!selected);
const imageExists = imageTitles.indexOf(title) !== -1
if (!imageExists) {
setImageTitles([...imageTitles, title]);
} else {
setImageTitles(imageTitles.filter(str => str !== title));
}
}, [selected, imageTitles])
But it didn't seem to do the trick. My guess is because imagetitles changes every time.
So, is it possible (for performance reasons) to avoid rerendering the list of images every time an image is selected/unselected?