React.children.map dont work with repeat for each element

Hello,

I have registered a custom Swiper component that maps children and creates a swiper slide for each child. Here’s the code:

export const Carousel: React.FC<CarouselProps> = ({ children }) => {
  return (
    <Swiper
      slidesPerView={"auto"}
      spaceBetween={24}
      autoplay={{
        delay: 2500,
        disableOnInteraction: false,
      }}
      modules={[Autoplay]}
    >
      {React.Children.map(children, (child, index) => {
        return <SwiperSlide key={`${index}`}>{child}</SwiperSlide>;
      })}
    </Swiper>
  );
};

While everything works properly when manually adding child elements:

When using a dynamic data list to repeat each element, React.Children.map receives the list as a single element instead of multiple elements:

How can i fix this issue ?

Hi @yuval222,

To resolve this issue, you can click on Edit Carousel → Advanced options → Use children for slides and bind dynamic slide content

Loom: Loom | Free Screen & Video Recording Software | Loom

Hi @manish-sharma

Thank you for your detailed response.

My use case is different because I have implemented a custom component called ‘Carousel’, as I require different functionality than what is provided by the built-in builder carousel.

As previously mentioned, passing a list of children manually works correctly. However, when binding it with a dynamic data list and repeating each item, it is passed as a single child containing a list of items. This causes React.Children.map to not work as expected.

Hi @yuval222,

If you could share the code for the custom carousel component, that would help us reproduce this from our end and possibly offer you a quick solution. Thank you!

Hi @manish-sharma

export const Carousel: React.FC<CarouselProps> = ({ children }) => {
  return (
    <Swiper
      slidesPerView={"auto"}
      spaceBetween={24}
      autoplay={{
        delay: 2500,
        disableOnInteraction: false,
      }}
      modules={[Autoplay]}
    >
      {React.Children.map(children, (child, index) => {
        return <SwiperSlide key={`${index}`}>{child}</SwiperSlide>;
      })}
    </Swiper>
  );
};

Hi @yuval222,

Could you also share the code for registering the swiper component with builder?

const CarouselWithChildren = withChildren(Carousel);

Builder.registerComponent(CarouselWithChildren, {
  name: "Carousel",
  inputs: [
    {
      name: "autoplay",
      friendlyName: "Autoplay",
      type: "boolean",
      defaultValue: true,
      helperText: "Enable autoplay",
    },
    {
      name: "slidesPerView",
      friendlyName: "Slides per view",
      type: "string",
      defaultValue: "auto",
      helperText: "Number of slides per view",
      enum: ["auto", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
    },
    {
      name: "effect",
      friendlyName: "Effect",
      type: "string",
      defaultValue: "fade",
      enum: ["fade", "creative"],
      showIf: (options: any) => options.get("slidesPerView") === "1",
    },
    {
      name: "spaceBetween",
      friendlyName: "Space between",
      type: "string",
      defaultValue: "24",
      helperText: "Space between slides",
      enum: ["24", "32"],
    },
  ],
});

@manish-sharma Have you managed to reproduce the issue?

Hi, @yuval222!

Yes, We have reproduced this issue and are working on a possible solution.