June 18, 2021
I needed the grey circles to change to elongated orange dots depending on the selected page. While it’s possible to achieve this using state and passing elements via props for CSS manipulation, I opted to explore using useRef.
const carouselRef = useRef([])
Initialize useRef with an empty array to store multiple DOM elements.
<Carousel>
<div className="circle" ref={(elem) => (carouselRef.current[0] = elem)} />
<div className="circle" ref={(elem) => (carouselRef.current[1] = elem)} />
<div className="circle" ref={(elem) => (carouselRef.current[2] = elem)} />
<div className="circle" ref={(elem) => (carouselRef.current[3] = elem)} />
<div className="circle" />
</Carousel>
Since carouselRef was initialized as an array, instead of ref={carouselRef}
, set ref={elem => (carouselRef.current[0] = elem)}
with respective index for each element. For instance, console.log(caraouselRef.current[0]
will log the first <div className="circle"></div>
. Now, we can manipulate four elements with a single ref.
useEffect(() => {
if (currentSlide !== 4) {
carouselRef.current[currentSlide].style.width = '2.8rem'
carouselRef.current[currentSlide].style.background = '#FF7134'
if (currentSlide !== 0) {
carouselRef.current[currentSlide - 1].style.width = '0.8rem'
carouselRef.current[currentSlide - 1].style.background = '#F7F0ED'
}
if (currentSlide !== 4) {
carouselRef.current[currentSlide + 1].style.width = '0.8rem'
carouselRef.current[currentSlide + 1].style.background = '#F7F0ED'
}
}
}, [currentSlide])
currentSlide
represents the current page number stored in state. Using useRef, adjust the width and background color of the grey circles corresponding to the current page number. When the next button is clicked, revert the left circle to its previous state if currentSlide
isn’t 0. Similarly, when the previous button is clicked, revert the right circle if currentSlide
isn’t 4.
While manipulating styles with useRef isn’t ideal, using state for CSS manipulation is generally better. However, useRef is useful for scenarios where you need to control multiple DOM elements in contexts other than CSS manipulation. If you encounter such situations, consider utilizing useRef as demonstrated here 😄
https://sukjae.github.io/posts/using-react-ref-for-multiple-dom-element-control