1

I've seen similar questions on SO about this error, but I haven't been able to fix my problem below.

The situation

The code at this link works:

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

However, what I don't like about it is that I need to repeat myself in the 'slides' array, by outlining the slide structure again and again (as you can see from lines 78 to 131).

I'm trying to replace that approach with a function that will generate the slide with the necessary information on demand. For example, I would keep all of the slide information in an array like this:

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

...and pass that information when needed to the return statement of the transition function on line 171 like this:

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

The problem

However, when I do that I get the following error when the first slide changes to the second: "Error: Rendered more hooks than during the previous render."

Why doesn't this work?

You can see my (not-working) attempt with this solution here:

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

Jason A
  • 81
  • 6

1 Answers1

1

Instead of having SlideFactory be a helper function that you call while rendering App, turn it into a component of its own. With the helper function version, you change how many times you call SlideFactory from one render to the next, which in turn changes how many hooks App calls, violating the rules of hooks.

But if you do it as a component, then it's perfectly fine to change how many components App returns, and when those components render, they'll only call one hook each.

// 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}/>
})}
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • What about when using some presentation framework like antd that takes in a list as parameter instead of displaying children as components? In that case you'd need to get the information in a regular list. How to do in that case, and why is react preventing it? – Nicolas Bernard Feb 01 '23 at 09:45
  • If you're asking specifically about the [antd list component](https://ant.design/components/list), the `renderItem` prop lets you decide what element(s) you want to render for each. That function is where you will return the `` element, and SlideFactory can call whatever hooks it needs. – Nicholas Tower Feb 01 '23 at 11:29
  • No I'm referring to the dataSource variable in Table, because the data is a regular object and not a component how can I populate it before display? Is it a limitation of react (can't populate a dynamic array of objects, need to go through components) , or should I have 1 hook that takes in all the objects at once and somehow dynamic calls happen there? (how?) – Nicolas Bernard Feb 01 '23 at 14:43
  • Sorry, i don't understand what you're trying to do and how it relates to the question i answered. I recommend you ask a new question, and include examples of the data and what hooks you're trying to use with that data. – Nicholas Tower Feb 01 '23 at 16:20