首页 > 解决方案 > React:渲染的钩子比之前的渲染更多?反应弹簧

问题描述

我在 SO 上看到过关于此错误的类似问题,但我无法在下面解决我的问题。

情况

此链接上的代码有效:

https://codesandbox.io/s/frosty-water-118xp?file=/src/App.js

然而,我不喜欢的是,我需要在“幻灯片”数组中重复自己,一遍又一遍地概述幻灯片结构(从第 78 行到第 131 行可以看到)。

我正在尝试用一种功能来替换这种方法,该功能将根据需要生成带有必要信息的幻灯片。例如,我会将所有幻灯片信息保存在一个数组中,如下所示:

const slideInformation = [
  {
    src: Image1,
    bigText: "ONE",
    littleText: "one",
  },
  {
    src: Image2,
    bigText: "TWO",
    littleText: "two",
  },
  {
    src: Image3,
    bigText: "THREE",
    littleText: "three",
  },
];

...并在需要时将该信息传递给第 171 行的转换函数的 return 语句,如下所示:

{transitions((style, i) => {
   const Slide = SlideFactory(style, slideInformation[i]);
   return <Slide />;
})}

问题

但是,当我这样做时,当第一张幻灯片更改为第二张时,我收到以下错误:“错误:渲染的钩子比上一次渲染期间更多。”

为什么这不起作用?

您可以在此处查看我的(不工作)尝试使用此解决方案:

https://codesandbox.io/s/adoring-mountain-bgd07?file=/src/App.js

标签: javascriptreactjsreact-hooksreact-spring

解决方案


与其让 SlideFactory 成为您在渲染 App 时调用的辅助函数,不如将其变成它自己的组件。使用辅助函数版本,你改变了从一个渲染到下一个渲染调用 SlideFactory 的次数,这反过来又改变了 App 调用的钩子的数量,违反了钩子的规则

但是如果你把它作为一个组件来做,那么改变 App 返回的组件数量是完全没问题的,当这些组件渲染时,它们每个只会调用一个钩子。

// You should name this using the `use` convention so that it's clear (to both
//   humans and lint tools) that it needs to follow the rules of hooks
const useZoomSpring = () => {
  return useSpring({
    from: { number: 1.0 },
    to: { number: 1.1 },
    config: { duration: duration },
  });
};

// It now expects a props object, not two separate parameters
const SlideFactory = ({ style, index }) => {
  const zoom = useZoomSpring();
  return (
    <SlideContainer style={style}>
      <ImageContainer
        src={slideInformation[index].src}
        style={{
          ...style,
          scale: zoom.number.to((n) => n),
        }}
      />
      <BigText>{slideInformation[index].bigText}</BigText>
      <LittleText>{slideInformation[index].littleText}</LittleText>
    </SlideContainer>
  );
}

// ...
{transitions((style, i) => {
  // creating a JSX element, not calling a function
  return <SlideFactory style={style} index={i}/>
})}

推荐阅读