Home > Enterprise >  I'm trying to make an infinite scrolling slider but the outcome is just a list
I'm trying to make an infinite scrolling slider but the outcome is just a list

Time:11-08

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>

  • Related