When trying static data the slider works fine but when I get my data from an API the design breaks down into a list and the slider stops working. The slider implementation is as follows:
js
$(".feedback-slider").bxSlider({
slideWidth: 177,
minSlides: 1,
maxSlides: 6,
slideMargin: 15,
touchEnabled: false,
});
React render
<ul className="feedback-slider">
{ApiRes.map((item, i) => {
return (
<li key={i}>
<div className="feedback-single-box">
<div className="card p-20">
<p className="m-0">{item.review}</p>
</div>
<div className="media">
<div className="thumbnail">
{
item.customerimage === null ?
<img
width="36px"
src = "/assets/img/avtar.png"
alt = "/"/>
:
<img
width="36px"
src={ImgPath item.customerimage}
alt={item.name}
/>
}
</div>
<div className="media-body">
<span className="designation">{item.name}</span>
<h6 className="title">{item.title}</h6>
</div>
</div>
</div>
</li>
);
})}
</ul>
The result I expected was an infinite scrolling slider but the outcome that i got was a list without the slider working at all. Could any one of you tell me where am i going wrong?
CodePudding user response:
That's because, at the time of executing the script of the slider, there are no elements inside the feedback-slider
element, I suggest you execute the script after receiving the data.
Maybe you need to add the script in the useEffect
hook and add the data and refs
to the li
elements as a dependency, so the script doesn't execute until the data reached out and the li
elements are created and mounted.
CodePudding user response:
As stated by Mina, when you execute the bxSlider
function, there aren’t any items inside the feedback-slider
list.
You need to use a useEffect React Hook or the componentDidMount lifecycle function in order to wait for your API to return some data and React to render the list items. Only then you can initialize bxSlider
.
Here is a code snippet that roughly reproduce what you want to achieve.
// Function to generate fake API response
function getFakeAPIResponse() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(Array.from({ length:10 }).map((_, i) => [{
review: `Review-${i}`,
name: `Name-${i}`,
title: `Title-${i}`
}]))
}, 1000)
})
}
// Slider component
function Slider() {
const [apiRes, setApiRes] = React.useState([])
React.useEffect(() => {
getFakeAPIResponse().then(setApiRes)
}, [])
React.useEffect(() => {
if (apiRes && apiRes.length > 0) {
$(".feedback-slider").bxSlider({
slideWidth: 177,
minSlides: 1,
maxSlides: 6,
slideMargin: 15,
touchEnabled: false,
})
}
}, [apiRes])
return (
<ul className="feedback-slider">
{apiRes.map((item, i) => (
<li key={i}>
<div className="feedback-single-box">
<div className="card p-20">
<p className="m-0">{item.review}</p>
</div>
<div className="media">
<div className="thumbnail">
<img src='https://source.unsplash.com/random/300x300' alt="/" />
</div>
<div className="media-body">
<span className="designation">{item.name}</span>
<h6 className="title">{item.title}</h6>
</div>
</div>
</div>
</li>
))}
</ul>
)
}
// Render React app
const root = ReactDOM.createRoot(document.querySelector('#root'))
root.render(<Slider />)
<!-- bxslider -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.min.js"></script>
<!-- react -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<!-- app -->
<main id='root'></main>