I want to add several infos sections in my front page, each having a button linking to an associated page on my website. Instead of writing a very large InfoSection component comprising all the sections (there will be 4 or 5), I tried to write only one section 'template' in the InfoSection component, and use a Data.js file where each object containing the information about each section, then displaying them on the main page like this:
<InfoSection {...homeObjOne}/>
<InfoSection {...homeObjTwo}/>
<InfoSection {...homeObjThree}/>
I then try to pass each page link in each object of Data.js, but then whenever I click on it, I receive the TypeError: Cannot read properties of undefined (reading 'pathname') I assume I'm doing something wrong with the component of 'buttonLabel' in the object from Data.js. What could I do to make it work?
The button works if I get rid of that 'buttonLabel' and just put a to='page1'
in the <Button>
component of index.js (<Button to='page1'>
), but that would mean each section links to the same page and I need each button to link to a different page...
The code is below (using only 2 sections at the moment, linking to page1 and page2)
Data.js from the InfoSection component
import React from 'react';
import { Link } from 'react-router-dom';
export const homeObjOne = {
description: <p>page 1</p>,
buttonLabel: <Link to="page1" target='_blank' style={{ textDecoration: 'none' }}>Go to page 1</Link>
};
export const homeObjTwo = {
description: <p>page 2</p>,
buttonLabel: <Link to="page2" target='_blank' style={{ textDecoration: 'none' }}>Go to page 2</Link>
};
index.js of the InfoSection component
import React, { useState, useEffect} from 'react';
import { Button } from '../ButtonElements';
import { InfoContainer, InfoWrapper, InfoRow, Column1, Column2, TextWrapper, TopLine, Heading, Subtitle, BtnWrap, ImgWrap, Img } from './InfoElements';
import VizSensor from 'react-visibility-sensor';
import { Fade } from '@mui/material';
const InfoSection = ({lightBg, id, imgStart, topLine, lightText, headline,darkText, description, buttonLabel, img, alt, primary, dark, dark2}) => {
let [active, setActive] = useState(false);
return (
<>
<InfoContainer lightBg={lightBg} id={id}>
<InfoWrapper>
<InfoRow imgStart={imgStart}>
<Column1>
<VizSensor onChange={(isVisible) => {
if(isVisible){
setActive(isVisible);
}
}}
>
<Fade in={active} timeout={1000} >
<TextWrapper>
<TopLine>{topLine}</TopLine>
<Fade in={active} timeout={1000} style={{ transitionDelay: `400ms` }}>
<Heading lightText={lightText}>{headline}</Heading>
</Fade>
<Fade in={active} timeout={1000} style={{ transitionDelay: `800ms` }}>
<Subtitle darkText={darkText}>{description}</Subtitle>
</Fade>
<BtnWrap>
<Button
smooth={true}
duration={500}
spy={true}
exact="true"
offset={-80}
primary={primary ? 1 : 0}
dark={dark ? 1: 0}
dark2={dark2 ? 1 : 0}
>{buttonLabel}</Button>
</BtnWrap>
</TextWrapper>
</Fade>
</VizSensor>
</Column1>
<Column2>
<ImgWrap>
<Img src={img} alt={alt}/>
</ImgWrap>
</Column2>
</InfoRow>
</InfoWrapper>
</InfoContainer>
</>
)
}
export default InfoSection
The ButtonElements.js file:
import styled from "styled-components";
import { Link } from "react-router-dom";
export const Button = styled(Link)`
border-radius: 50px;
background: ${({primary}) => (primary ? '#F59AA6' : '#010606')};
white-space: nowrap;
padding: ${({fontBig}) => (fontBig ? '20px' : '16px')};
outline: none;
border: none;
cursor: pointer;
display: flex;
justify-content: center;
text-decoration: none;
align-items: center;
transition: all 0.2s ease-in-out;
&:hover {
transition: all 0.2s ease-in-out;
background: ${({primary}) => (primary ? '#fff' : '#F59AA6')};
}
`