Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

116
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda