Here I want to display the current image when I click on the "fullscreen" span tag.
export default function CandidateSlider({ componentData }) {
const [showModal, setShowModal] = useState(false);
const [imgSrc, setImgSrc] = useState("");
const [photoslider, setPhotoSlider] = useState([]);
const [currentDataItem, setCurrentDataItem] = useState(null);
const fetchData = async () => {
let api_data = await fetchUtility(componentData?.api_url, []);
setPhotoSlider(api_data);
};
useEffect(() => {
fetchData();
}, []);
const changeModal = (src, modal_state) => {
setImgSrc(src);
setShowModal(modal_state);
};
const NextBtn = (props) => {
const { className, onClick } = props;
return <div className={className} onClick={onClick}></div>;
};
const PreviousBtn = (props) => {
const { className, onClick } = props;
return <div className={className} onClick={onClick}></div>;
};
var settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
prevArrow: <PreviousBtn />,
nextArrow: <NextBtn />,
};
return (
<>
<section className="n18_ele_candislider_comp" id="slick_slider">
<div className="glide n18_candislider">
<span
className="fullscreen"
onClick={() => {
changeModal(currentDataItem, true);
}}
>
<span className="fullscreen_labl">
fullscreen
</span>
</span>
<Slider {...settings}>
{Object.keys(photoslider).map(([dataitem, index]) => {
// Here's the problem.
setCurrentDataItem(photoslider?.[dataitem]?.thumbnail);
return (
<>
<div key={index} className="consti_prty_slidr">
<div className="imgeSlidr" key={index}>
<img
width="100%"
height="100%"
src={photoslider?.[dataitem]?.thumbnail}
/>
</div>
<p className="const_slidr_det">
{photoslider?.[dataitem]?.title}
</p>
</div>
</>
);
})}
</Slider>
</div>
</section>
</>
);
}
It is throwing an error: "Error: too many re-renders. React limits the number of renders to prevent an infinite loop."
This error occurs because I used setCurrentDataItem(photoslider?.[dataitem]?.thumbnail)
inside the map function.
But without this, how can I access the current ‘dataitem’ outside of the map function?
2
Answers
Changing state should only happen as a reaction to some event. Changing it in your render triggers a re-render and thus an infinite loop.
Assuming
Slider
is the component from React Slick, use either of the slide change hooks to capture the current slide index.It also looks like
api_data
is an object but you initialise it as an array and really only seem interested in treating it like an array. I would map the object data to an array to make things easierThe reason that you are experiencing this issue, is because you are calling
fetchData()
within anuseEffect()
, where you probably want to call it in auseCallback()
instead.useEffect()
runs on every re-render. You have also not bound youruseEffect()
to any state dependencies, so every time the state changes, that effect will be run. This is why your code is infinite looping when you change the state within your template, as it fetches data again, and then rerenders, because you are settingphotoSlider
which is also part of your template.Put your
fetchData()
call into auseCallback()
and perhaps have it depend oncurrentDataItem
This way, when
currentDataItem
changes, the callback will be called.