I was trying to implement a slider using react-glider. where I was changing the background color of the slider element when it is clicked. and I am maintaining a state variable selected to keep track of the currently clicked slide inside the parent component and passed that variable and handler function as props inside child component.
So the issue that currently running out here is that when I click on the slider element (which is out of view currently ) the react-glider component re-renders which in turn causes the slider element to go out of view and it displays the slider from the start rather than just displaying the currently clicked one. So how to prevent parent Component from re-render and only cause the child to re-render based on props passed to it so that the currently clicked slide will not go out of focus. i have optimized it bit using useCallback and memo but anyhow parent would be re-rendered.and also tried to maintain a ref for keeping track of the clicked slider element but i was not able to implement it .
here is a demo of the issue : https://gifyu.com/image/SwjXG
and code-sandbox link : https://codesandbox.io/s/silly-cray-b2fwbj?file=/src/App.js
import "./styles.css";
import "glider-js/glider.min.css";
import React, { useCallback, useMemo } from "react";
import Glider from "react-glider";
const slides = [
{ index: 1, title: "Slide 1" },
{ index: 2, title: "Slide 2" },
{ index: 3, title: "Slide 3" },
{ index: 4, title: "Slide 4" },
{ index: 5, title: "Slide 5" },
{ index: 6, title: "Slide 6" },
{ index: 7, title: "Slide 7" },
{ index: 8, title: "Slide 8" },
{ index: 9, title: "Slide 9" },
{ index: 10, title: "Slide 10" }
];
export default function App() {
const [selected, setSelected] = React.useState(0);
const handleClick = useCallback((id) => {
if (id !== selected) {
setSelected(id);
}
}, []);
console.log("Parent Re Rendered");
return (
<div className="w-[100%]">
<Glider
slidesToShow={"auto"}
slidesToScroll={"auto"}
draggable
hasDots
scrollLock
>
{slides.map((category, id) => (
<MemoizedCategory
handleClick={handleClick}
key={id}
selected={selected === category.index}
title={category.title}
index={category.index}
/>
))}
</Glider>
</div>
);
}
const MemoizedCategory = React.memo(Category);
function Category({ title, selected, handleClick, index }) {
console.log("Re Rendered ", index);
return (
<div
onClick={() => handleClick(index)}
className={`card ${selected === true ? `bg-blueviolet` : `bg-black`} `}
>
<h1>{title}</h1>
</div>
);
}
#style.css
.App {
font-family: sans-serif;
text-align: center;
}
.card {
display: flex;
height: 100px !important;
width: 200px !important;
background: black;
color: white;
margin: 2px;
}
.bg-blueviolet {
background-color: blueviolet;
}
.bg-black {
background-color: black;
}