将React的ImageSlider适配到Next.js中。

huangapple go评论93阅读模式
英文:

Adapt a react ImageSlider to NextJS

问题

I have the following image slider in React, it's working 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's not working in NextJS, I adapted it a bit to fix the errors:

"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 have tried to add 'use client' on top of the components and to modify the code to fix the errors my IDE was displaying, all the images in the array appear in the browser network tab.

英文:

i have the following image slider in React, it's working as expected :

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

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

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

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

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

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

export default ImageSlider;

but it's not working in NextJS, i adapted it a bit to fix the errors :

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

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

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

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

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

export default ImageSlider;

I have tried to add 'use client' on top of the components and to modify the code to fix the errors my IDE was displaying, all the images in the array appears in the browser network tab.

答案1

得分: 0

在Next.js中,你不能直接在顶级组件中使用React hooks。相反,你可以在Next.js的useEffect函数中使用useEffect钩子。以下是如何修改你的代码以使其在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);
    };
  }, []); // 空的依赖数组,以便只运行一次效果

  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;

希望这能帮助你在Next.js中使用React hooks。

英文:

In Next.js, you can't use React hooks directly in the top-level component. Instead, you can use the useEffect hook in the useEffect function of Next.js. Here's how you can modify your code to make it work in Next.js:

import { useState, useEffect } from &quot;react&quot;;

const imgs = [&quot;/images/1.jpg&quot;, &quot;/images/2.gif&quot;, &quot;/images/3.jpg&quot;];
const ImageSlider = () =&gt; {
const [current, setCurrent] = useState(0);

useEffect(() =&gt; {
const interval = setInterval(() =&gt; {
  setCurrent((current) =&gt; (current + 1) % imgs.length);
}, 2000);

return () =&gt; {
  clearInterval(interval);
};
}, []); // Empty dependency array to run effect only once

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

 export default ImageSlider;

huangapple
  • 本文由 发表于 2023年6月5日 20:45:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76406557.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定