简体   繁体   中英

How can i achieve 100% reusability of that react-bootstrap component?

I am trying to create a reusable carousel using react-bootstrap, i could create that one"

const ReusableCarousel = (props) => {
    return (
        <Carousel className="mt-4 border">
            {props.items.map((item, index) => {
                return (
                    <Carousel.Item key={index}>
                        <Row> 
                            {props.children}
                        </Row>
                    </Carousel.Item>
                );
            })}
        </Carousel>
    );
}

Now as you see it is reusable till the point of the carousel item, props.children may represent multiple elements per one slide or single element per slide, but i can not achieve that according to my logic

in the parent:

   <ReusableCarousel items={categories}> //categories is an array of arrays of objects
      {
         //item prop should be passed here to carouselItemCategories component
         //but i couldn't find a way to achieve that
         <CarouselItemCategories key={i} /> 
      }
   </ReusableCarousel>

carouselItemCategories Component:

const CarouselItemCategories = (props) => {
    //still in my dreams
    const { item } = props;
    return (
        <>
            {
                item.map((c, index) => {
                    return (
                        <Col key={index}>
                            //a category card here
                        </Col>
                    );
                })
            }
        </>
    );
}

Now i know what makes it work, it is about passing item prop(which represent an array of objects represents fraction of my categories) but i could not find any way to achieve that

you can imagine categories like that:

const categories = [
   [
    {
      title: 'Laptops',
       background: 'red'
    },
    {
      title: 'Tablets',
      background: 'blue';
    }
   ],
   [
    {
      title: 'Mouses',
       background: 'yellow'
    },
    {
      title: 'Printers',
      background: 'orange';
    }

   ]
]

If I understand you correctly, you want to use each of the items from your ReusableCarousel to generate a new CarouselItemCategories with the individual item passed in as a prop?

If so, you may want to take a look at the cloneElement function . Effectively, inside your mapping of the items prop, you would create a clone of your child element, and attach the individual item as a prop to that clone. Something like this:

const ReusableCarousel = (props) => {
  return (
      <Carousel className="mt-4 border">
          {props.items.map((item, index) => {
              return (
                  <Carousel.Item key={index}>
                      <Row> 
                          {React.cloneElement(props.children, { item })}
                      </Row>
                  </Carousel.Item>
              );
          })}
      </Carousel>
  );
}

I just found another solution by using react context, i created a CarouselContext module:

import React from 'react';

const CarouselContext = React.createContext([]);

export const CarouselProvider = CarouselContext.Provider;
export default CarouselContext

and then in the ReusableCarousel component :

import { CarouselProvider } from './carouselContext'

const ReusableCarousel = (props) => {
    return (
        <Carousel >
            {props.items.map((item, index) => {
                return (
                    <Carousel.Item key={index} >
                        <Row >
                            {
                              <CarouselProvider value={item}>
                                  {props.children}
                              </CarouselProvider>
                            }
                        </Row>
                    </Carousel.Item>
                );
            })}
        </Carousel>
    );
}


and then using the context to get item global variable

const CarouselItemCategories = () => {
    const item = useContext(CarouselContext);

    return (
        <>
            {
                item.map((c, index) => {
                    return (
                        <Col>
                           //category card here
                        </Col>
                    );
                })
            }
        </>
    );
}


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM