Repository: recharts/recharts
File: src/polar/RadialBar.tsx (TypeScript)

Code before:
                const prev = prevData && prevData[index];

                if (prev) {
                  const interpolatorStartAngle = interpolateNumber(prev.startAngle, entry.startAngle);
                  const interpolatorEndAngle = interpolateNumber(prev.endAngle, entry.endAngle);

                  return {
                    ...entry,
                    startAngle: interpolatorStartAngle(t),
                    endAngle: interpolatorEndAngle(t),
                  };
                }
                const { endAngle, startAngle } = entry;
                const interpolator = interpolateNumber(startAngle, endAngle);

                return { ...entry, endAngle: interpolator(t) };
              });

        if (t > 0) {
          // eslint-disable-next-line no-param-reassign
          previousSectorsRef.current = stepData ?? null;
        }

        return (
          <Layer>
            <RadialBarSectors sectors={stepData ?? []} allOtherRadialBarProps={props} showLabels={!isAnimating} />
          </Layer>
        );
      }}
    </Animate>
  );
}

function RenderSectors(props: RadialBarProps) {
  const { data = [], isAnimationActive } = props;

  const previousSectorsRef = useRef<ReadonlyArray<RadialBarDataItem> | null>(null);
  const prevData = previousSectorsRef.current;

  if (isAnimationActive && data && data.length && (!prevData || prevData !== data)) {
    return <SectorsWithAnimation props={props} previousSectorsRef={previousSectorsRef} />;
  }

  return <RadialBarSectors sectors={data} allOtherRadialBarProps={props} showLabels />;
}

interface InternalRadialBarProps {
  className?: string;
  angleAxisId?: AxisId;
  radiusAxisId?: AxisId;
  startAngle?: number;

Review comment (bug):
The empty arrays defined inline may cause extra re-renders (and infinite loops in the worst case). Try to return them from selectors (where they will be automatically memoized) or declare a const outside of the component so that it stays the same instance and React will not trigger a new render.

Code after:
            ? data
            : (data ?? STABLE_EMPTY_ARRAY).map((entry, index) => {
                const prev = prevData && prevData[index];

                if (prev) {
                  const interpolatorStartAngle = interpolateNumber(prev.startAngle, entry.startAngle);
                  const interpolatorEndAngle = interpolateNumber(prev.endAngle, entry.endAngle);

                  return {
                    ...entry,
                    startAngle: interpolatorStartAngle(t),
                    endAngle: interpolatorEndAngle(t),
                  };
                }
                const { endAngle, startAngle } = entry;
                const interpolator = interpolateNumber(startAngle, endAngle);

                return { ...entry, endAngle: interpolator(t) };
              });

        if (t > 0) {
          // eslint-disable-next-line no-param-reassign
          previousSectorsRef.current = stepData ?? null;
        }

        return (
          <Layer>
            <RadialBarSectors
              sectors={stepData ?? STABLE_EMPTY_ARRAY}
              allOtherRadialBarProps={props}
              showLabels={!isAnimating}
            />
          </Layer>
        );
      }}
    </Animate>
  );
}

function RenderSectors(props: RadialBarProps) {
  const { data = [], isAnimationActive } = props;

  const previousSectorsRef = useRef<ReadonlyArray<RadialBarDataItem> | null>(null);
  const prevData = previousSectorsRef.current;

  if (isAnimationActive && data && data.length && (!prevData || prevData !== data)) {
    return <SectorsWithAnimation props={props} previousSectorsRef={previousSectorsRef} />;
  }

  return <RadialBarSectors sectors={data} allOtherRadialBarProps={props} showLabels />;
}