search

Home  >  Q&A  >  body text

Convert React ImageSlider to NextJS

I have the following image slider in React and it works as expected:

import React, { useState, useEffect } from "react";
import item1 from "./../assets/images/items/1.jpg";
import item2 from "./../assets/images/items/2.gif";

const imgs = [item1, item2]; // Array of images

const ImageSlider = () => {
  const [current, setCurrent] = useState(0); // Initialize state to display the first image

  // Change image every 2 seconds
  useEffect(() => {
    const interval = setInterval(() => {
      setCurrent((current) => (current + 1) % imgs.length); // Move to the next image, go back to the first image after the last
    }, 4000); // Change every 2 seconds

    return () => {
      clearInterval(interval); // Clean up on unmount
    };
  }, []);

  return (
    <div className="relative">
      <img
        src={imgs[0]}
        className="w-full h-auto opacity-0"
        alt="placeholder"
      />
      {imgs.map((img, index) => (
        <img
          key={index}
          src={img}
          alt={`slide-img-${index}`}
          className={`absolute top-0 transition-opacity duration-1000 ease-in-out ${
            current === index ? "opacity-100" : "opacity-0"
          } w-full h-auto`}
        />
      ))}
    </div>
  );
};

export default ImageSlider;

But it doesn't work in NextJS, I made some modifications to fix the error:

"use client";
import React, { useState, useEffect } from "react";

const imgs = ["/images/1.jpg", "/images/2.gif", "/images/3.jpg"];
const ImageSlider = () => {
  const [current, setCurrent] = useState(0); // Initialize state to display the first image

  // Change image every 2 seconds
  useEffect(() => {
    const interval = setInterval(() => {
      setCurrent((current) => (current + 1) % imgs.length); // Move to the next image, go back to the first image after the last
    }, 2000); // Change every 2 seconds

    return () => {
      clearInterval(interval); // Clean up on unmount
    };
  }, []);

  return (
    <div className="relative">
      <img
        src={imgs[0]}
        className="w-full h-auto opacity-0"
        alt="placeholder"
      />
      {imgs.map((img, index) => (
        <img
          key={index}
          src={img}
          alt={`slide-img-${index}`}
          className={`absolute top-0 transition-opacity duration-1000 ease-in-out ${
            current === index ? "opacity-100" : "opacity-0"
          } w-full h-auto`}
        />
      ))}
    </div>
  );
};

export default ImageSlider;

I tried adding "Use Client" at the top of the component and modified the code to fix the error shown by the IDE, all the images in the array were shown in the browser network tab.

P粉225961749P粉225961749256 days ago2456

reply all(1)I'll reply

  • P粉194541072

    P粉1945410722024-04-06 00:10:09

    In Next.js, you cannot use React hooks directly in top-level components. Instead, you can use the useEffect hook in Next.js's useEffect function. Here's how to modify your code to run in Next.js:

    import { useState, useEffect } from "react";
    
    const imgs = ["/images/1.jpg", "/images/2.gif", "/images/3.jpg"];
    const ImageSlider = () => {
    const [current, setCurrent] = useState(0);
    
    useEffect(() => {
    const interval = setInterval(() => {
      setCurrent((current) => (current + 1) % imgs.length);
    }, 2000);
    
    return () => {
      clearInterval(interval);
    };
    }, []); // Empty dependency array to run effect only once
    
    return (
    
    placeholder {imgs.map((img, index) => ( {`slide-img-${index}`} ))}
    ); }; export default ImageSlider;

    reply
    0
  • Cancelreply