React/NextJS 使用 UseEffect 错误:渲染的钩子比上一次渲染期间更多

Posted

技术标签:

【中文标题】React/NextJS 使用 UseEffect 错误:渲染的钩子比上一次渲染期间更多【英文标题】:React/NextJS using UseEffect Error: Rendered more hooks than during the previous render 【发布时间】:2021-09-29 09:01:54 【问题描述】:

我是使用 ReactJS/NextJS 的初学者。我正在创建一个轮播组件以使用 NextJS 框架中的图像优化功能。轮播组件工作正常,我想在传递持续时间的道具时自动添加轮播下一张幻灯片。我试图用setTimeoutUseEffect 钩子中创建一个函数来执行我的下一张幻灯片。

我试过这段代码:

import React,  useState, useEffect  from 'react';
import styles from 'components/shared/carousel/carouselStyles.css';
import NavigateBeforeIcon from '@material-ui/icons/NavigateBefore';
import NavigateNextIcon from '@material-ui/icons/NavigateNext';
import Image from 'next/image';

const Carousel = (props) => 
  const  slides, slideshow  = props;

  const [current, setCurrent] = useState(0);

  const length = slides && slides.length;

  const nextSlide = () => 
    setCurrent(current === length - 1 ? 0 : current + 1);
  ;

  const prevSlide = () => 
    setCurrent(current === 0 ? length - 1 : current - 1);
  ;

  if (!Array.isArray(slides) || slides.length <= 0) 
    return null;
  

  useEffect(() => 
    if (slideshow > 0) 
      let interval = setInterval(() => 
        nextSlide();
      , slideshow);
      return () => clearInterval(interval);
    
  , [current, slideshow]);

  return (
    <section className="slider">
      <NavigateBeforeIcon className="left-arrow" onClick=prevSlide />
      <NavigateNextIcon className="right-arrow" onClick=nextSlide />
      slides.map((slide, index) => 
        return (
          <>
            <div
              className=index === current ? 'slide active' : 'slide'
              key=index
            >
              index === current && (
                <Image
                  src=slide.feature_image
                  
                  className="image"
                  width=1600
                  height=600
                />
              )
            </div>
          </>
        );
      )
      <div className="dots-con">
        slides.map((slide, index) => 
          return (
            <span
              className=index === current ? 'dot active' : 'dot'
              key=index
            ></span>
          );
        )
      </div>
    </section>
  );
;

export default Carousel;

但这给了我Error: Rendered more hooks than during the previous render的错误

如果我要评论useEffect,那么它工作正常,但没有想出我想要的自动播放轮播

【问题讨论】:

【参考方案1】:

这是您的 useEffect Hook 中的语法问题。

您不应该将书面语句包装在 if 条件中。 它从不执行 useEffect 的返回来清理。

useEffect(() => 
    let interval;
    if (slideshow > 0) 
      interval = setInterval(() => 
        nextSlide();
      , slideshow);
    
    return () => 
      clearInterval(interval);
    ;
  , [current, slideshow]);

【讨论】:

分享代码沙箱链接了解更多详情【参考方案2】:

像这样在钩子之后移动你的条件:

  useEffect(() => 
    if (slideshow > 0) 
      let interval = setInterval(() => 
        nextSlide();
      , slideshow);
      return () => clearInterval(interval);
    
  , [current, slideshow]);


 if (!Array.isArray(slides) || slides.length <= 0) 
        return null;
 

在这里阅读更多关于反应钩子规则link

【讨论】:

以上是关于React/NextJS 使用 UseEffect 错误:渲染的钩子比上一次渲染期间更多的主要内容,如果未能解决你的问题,请参考以下文章

从零搭建一个基于React+Nextjs的SSR网站:如何搭建服务器并部署Nextjs项目

React + NextJS - 受保护的路线

React/nextJS:如何调试 s-s-r react 应用的不同节点?

如何将Drift bot JS代码与静态React NextJs应用(着陆页)整合?

React/Nextjs 上下文提供程序状态在第一次加载/刷新时无法访问,但在状态更改时工作正常

如何为静态导出的 NextJS 应用程序设置 basePath