Search code examples
javascriptreactjswebstyled-components

Exporting data to a variable number of components in React


I have a component that takes in data for my website (InfoSection.js)

import React from 'react'
import {Button} from '../ButtonElement'
import {InfoContainer, InfoWrapper, InfoRow, Column1, Column2, TextWrapper, TopLine, Heading, Subtitle, BtnWrap, ImgWrap, Img, alt} from './InfoElements'

const InfoSection = ({lightBg, id, imgStart, topLine, lightText, headline, darkText, description, ButtonLabel, img, alt}) => {
    return (
        <InfoContainer lightBg={lightBg} id={id}>
            <InfoWrapper>
                <InfoRow imgStart={imgStart}> 
                    <Column1>
                    <TextWrapper>
                        <TopLine>{topLine}</TopLine>
                        <Heading lightText={lightText}>{headline}</Heading>
                        <Subtitle darkText={darkText}>{description}</Subtitle>
                    </TextWrapper>
                    </Column1>
                    <Column2>
                        <ImgWrap>
                            <Img src={img} alt={alt}/>
                        </ImgWrap>
                    </Column2>
                </InfoRow>
            </InfoWrapper>
        </InfoContainer>
    
    )
}

export default InfoSection

Here is where I send the data (Data.js)

export const homeObjOne = {
    id: 'about',
    lightBg: false,
    lightText: true,
    topLine: 'About',
    headline: 'I am a Recent Laurier Grad',
    description: 'I am currently looking for work as a web developer or FullStack Developer',
    buttonLabel: '',
    imgStart: false,
    img: require('../../images/LinkedInPicture.jpg').default,
    alt: 'Picture of myself',
    dark: true,
    primary: true,
    darkText: false
};

This works fine, but this doesn't fit all of my information sections because I want one that has 3 <heading> and <Subtitle> tags without creating a whole new component. I want to be able to input the number of these tags that will appear but I have no idea how to go about doing that, and then I also need to be able to pass in multiple headings and subtitles into one component from my data.js


Solution

  • Your input data may accept an array of titles instead of a single attribute:

    titles:[{headline:"headerA",description:"A subtitle"},{headline:"headerB",description:"B subtitle"},{headline:"headerC",description:"C subtitle"}]
    

    Then in your render method you could use map keyword:

    return (
     <container>
     titles.map( (title, index) => ( 
                        <TextWrapper key={index}>
                            { title.topLine ? (<TopLine>{title.topLine}</TopLine>):null}
                            <Heading lightText={title.lightText}>{title.headline}</Heading>
                            <Subtitle darkText={title.darkText}>{title.description}</Subtitle>
                        </TextWrapper>
     )
     </container>