Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

112
Views
Create a function that returns the next/prev 4 results in an array of objects

I'm trying to create a function that renders the next & prev 4 results in an array of objects onClick. Currently I am only returning the first 4 items and their images and adjusting the values in the return statement onClick and am not happy with this solution. Any pointers?

const ImageSlider = ({ loadData, data, setData }) => {
  const [current, setCurrent] = useState(0);
  const length = data.length;
  const [test, setTest] = useState(0);
  const [another, setAnother] = useState(4);

  useEffect(() => {
    loadData().then((data) => setData(data));
  }, []);

  const getNextSlide = () => {
    setCurrent(current === length - 1 ? 0 : current + 1);
    if (current / 3 === 1) {
      setTest(test + 4);
      setAnother(another + 4);
    }
  };

  const getPrevSlide = () => {
    setCurrent(current === 0 ? length - 1 : current - 1);
    // setTest(test - 1);
    // setAnother(another - 1);
  };

  console.log(current);

  if (!Array.isArray(data) || length <= 0) {
    return null;
    // Need that error message here
  }

  return (
    <div className="slider">
      <FaArrowCircleLeft className="slider-left-arrow" onClick={getPrevSlide} />
      <FaArrowCircleRight
        className="slider-right-arrow"
        onClick={getNextSlide}
      />
      {data.slice(test, another).map((program, index) => {
        return (
          <div
            className={
              index === current
                ? "slider-active-program"
                : "slider-inactive-program"
            }
            key={index}
          >
            <img
              src={program.image}
              alt="program"
              className="slider-program-image"
            />
          </div>
        );
      })}
    </div>
  );
};

export default ImageSlider;

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

This may be one possible approach to achieve the desired objective:

const ImageSlider = ({ loadData, data, setData }) => {
  const imageLength = 4;    // number of images to be shown per-page
  const totalImages = data.length;
  const [startAt, setStartAt] = useSate(0);  // start rendering from image-0
  useEffect(() => {
    loadData().then((data) => setData(data));
  }, []);
  const switchImages = (direction = 'forward') => (
    setStartAt(prev => {
      if (direction === 'forward') {
        // if there are more images, reposition 'startAt' to next set
        if (prev + imageLength < totalImages) return prev + imageLength;
        return 0; // reset back to image-0
      } else {
        // if there is previous set, reposition to it's start
        if (prev - imageLength >= 0) return prev - imageLength;
        // otherwise, reposition to the start of the last-set
        return (Math.floor((totalImages - 1) / imageLength) * imageLength)
      };
    })
  );

  return (
    <div className="slider">
      <FaArrowCircleLeft
        className="slider-left-arrow"
        onClick={() => switchImages('reverse')}
      />
      <FaArrowCircleRight
        className="slider-right-arrow"
        onClick={() => switchImages()}
      />
      {Array.isArray(data) && data.filter((el, idx) => idx >= startAt && idx < (startAt + imageLength)).map((program, index) => {
        return (
          <div
            className={
              index === current
                ? "slider-active-program"
                : "slider-inactive-program"
            }
            key={index}
          >
            <img
              src={program.image}
              alt="program"
              className="slider-program-image"
            />
          </div>
        );
      })}
    </div>
  );
};

export default ImageSlider;

Explanation

  • imageLength is fixed (set to 4)
  • startAt is a state-variable (initially set to 0)
  • data is rendered on return only when it is an Array
  • switchImages is a method invoked on both left-arrow and right-arrow click-events (changing the parameter direction to reverse on left-arrow)
  • startAt is updated based on the direction, the prev value, the totalImages and imageLength.

Suggestion

If one needs to render a message to the user that the data array is either not-yet-loaded or it is empty, it may be acccomplished by changing the {Array.isArray(data) && .... into a conditional such as {Array.isArray(data) ? ....<existing> : <some message here>.

Warning

The above code is only an approach. It is not tested & may contain syntax errors or other issues. Please use comments to share feedback and this answer may be updated accordingly.

about 4 years ago · Juan Pablo Isaza Report

0

I don't think you have to change much about your approach to get what you're looking for here.

To render the images to the left and right of your current selection and allow looping from the front to the back (as it looks like you want to do), we can paste a copy of the array to the front and back and select the middle slice. It's a little bit like this:

example image of tri duplicated array and taking a slice in the middle

The implementation would just require you to replace the current .map(...) method in your return statement with this one:

[...data, ...data, ...data].slice(
  length + current - peekLeft,
  length + current + peekRight + 1
).map((program, index) => {
  ...
}

And then you can also remove the test and another state objects as well since they aren't necessary. You just need to add the peekLeft and peekRight or replace them inline inside the .map(...) statement. The first option may look something like this:

const peekLeft = 4;
const peekRight = 4;

const ImageSlider = ({ loadData, data, setData }) => {
  ...
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!