Unable to load pdf in react - reactjs

I'm trying to load a pdf file for the user in another tab once they click a button but it's not working and I'm not sure how to make it work. Could I have some help in doing this?
I defined a function PdfViewer() and I call it when a button is clicked using onClick(), but once the button is clicked I get this error:
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
Here's my code:
import "../styles/ProjectDetails.css";
import React, { useState } from 'react'
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack'
function PdfViewer() {
const [numPage, setNumPages] = useState(null);
const [pageNumber, setPageNumber] = useState(1);
function onDocumentLoadSuccess({numPages}) {
setNumPages(numPage);
setPageNumber(1);
}
return (
<div>
<header>
<Document file="../pdfs/Mini_Case_Study_15.pdf" onLoadSuccess={onDocumentLoadSuccess}>
<Page height="600" pageNumber={pageNumber}></Page>
</Document>
</header>
</div>
)
}
const ProjectDetails = ({ project }) => {
return (
<div className="card-grid">
<div className="card">
<div className="card-header card-image">
<img src="https://c4.wallpaperflare.com/wallpaper/672/357/220/road-background-color-hd-wallpaper-thumb.jpg"/>
</div>
<div className="card-title"><strong>{project.sdg}</strong></div>
<div className="card-body">
<strong>Goal:</strong> {project.goal}
</div>
<div className="card-themes">
<strong>Themes:</strong> {project.theme.map((theme)=>{return theme + ', '})}
</div>
<div className="card-assignment">
<strong>Assignment Type:</strong> {project.assignment_type}
</div>
<div className="card-footer">
<button className="btn">Details</button>
{project.assignment_type === 'Mini Case Studies' &&
<>
<button className="btn btn-outline">Download</button>
{/* <button onClick={PdfViewer} className="btn">Preview</button> */}
</>
}
</div>
</div>
</div>
)
}
export default ProjectDetails
How do I make it so that once the user clicks the button, it takes them to another page with the pdf file shown?

You could try this approach here, inserting the Preview as a Component.
const ProjectDetails = ({ project }) => {
const [preview, setPreview] = useState(false)
const onClickToPreviewPDF = () => {
setPreview(preview ? false : true);
}
return (
<>
<div className="card-grid">
<div className="card">
<div className="card-header card-image">
<img src="https://c4.wallpaperflare.com/wallpaper/672/357/220/road-background-color-hd-wallpaper-thumb.jpg"/>
</div>
<div className="card-title"><strong>{project.sdg}</strong></div>
<div className="card-body">
<strong>Goal:</strong> {project.goal}
</div>
<div className="card-themes">
<strong>Themes:</strong> {project.theme.map((theme)=>{return theme + ', '})}
</div>
<div className="card-assignment">
<strong>Assignment Type:</strong> {project.assignment_type}
</div>
<div className="card-footer">
<button className="btn">Details</button>
{project.assignment_type === 'Mini Case Studies' &&
<>
<button className="btn btn-outline">Download</button>
<button onClick={onClickToPreviewPDF} className="btn">Preview</button>
</>
}
</div>
</div>
</div>
{preview && <PdfViewer />}
</>
)
}

Related

Adding items to cart in react js

In reactjs, what code would I have to write in my two components(homepage.js with an add-to-cart button and a checkout page with a clear cart button? This is my Homepage.js where I fetch the items from my backend server, map, and display them on the page.
function Home() {
const [data, setData] = useState([]);
useEffect(() => {
// auto-login
fetch("/coffees").then((res) => {
if (res.ok) {
res.json().then((data) => setData(data))
}
});
}, [])
console.log(data)
return (
<>
<div className="box">
<div className="projo">
<h2 >Welcome to Coffee-cafe</h2>
</div>
<div className="projects">
{data.map((data) =>{
return(
<div className="card">
<img className="avatar" src={data.coffee_image} alt="coffee"></img>
<div className="card-content">
<h4><b>{data.coffee_name}</b></h4>
<p id="desc">{data.description}</p>
<p className="price">{data.price}</p>
{/* <p>{data.category}</p> */}
<button onClick={() => ({})} className="btn1" id="btn1">Add to Cart</button>
</div>
</div>
)
})}
</div>
</div>
</>
)
}
export default Home;
For the Checkout.js, this is what I have currently.
function Checkout() {
return (
<>
<div className="section">
<div className="photo">
<img className="dp" src={image1} alt="coffee"></img>
<div className="info">
<h3>Coffee:</h3>
<p>Price:</p>
<p>Category:</p>
<div className="check-out-btn">
{/* <button className="add">AddToCart</button> */}
<button className="delete">ClearCart</button>
</div>
</div>
</div>
</div>
take a look for a global states like redux , context,or zustand
for my recommendation, I suggest zustand is less code than context and redux and short learning curve
carts =[]
setItemToCart(item){
const isExist = carts.find(c => c.id ===item.id)
if(isExit){
const qty = isExit.qty+item.qty
const newItem= {...item,qty}
// push is not recommended to use because it mutates state
carts.push(newItem)
}else{
carts.push(item)
}
}

why link doesn't work when I use getStaticProps?

I'm new in next js and I'm working on project using NextJS. I have some lots in my items page that shows lots currently(pagination/items.tsx) and I also have lotDetails page that I want it to show details of each lot using dynamic route(lotDetails\id\index.tsx).
This is the folder structure:
Now when I click the Link in Items.tsx I expect it to go to lotDetails page and pass the props, but nothing happens! (It stays on Items page!). here is Items.tsx:
import React from 'react'
import Link from "next/link"
const Items = ({currentItems}:{currentItems:any}) => {
console.log(currentItems)
// const ids=currentItems.map((el:any)=>el.id)
// const paths=ids.map((el:any)=>{params:{id:el.toString()}})
// console.log(paths)
return (
<>
<div className="container">
<div className="row">
{currentItems.map((el:any)=><div className="col-md-3 ">
//this should be linked to lotDetails page!
<Link href={{pathname:"../lotDetails/[id]",query:{id:JSON.stringify(el.id),title:el.title,image:el.image,description:el.description.toString(),rate:el.rating.rate,count:el.rating.count,price:el.price},}} as={`/lotDetails/${el.id.toString()}`}>
<div className="lot">
<div className="img-container">
<img src={el.image}/>
</div>
<div className="title">
{el.title}
</div>
<div className="price">
<span className="price-title">Price:</span>
<span>{el.price}</span>
</div>
</div>
</Link>
</div>)}
</div>
</div>
</>
)
}
export default Items;
I'm using getStaticProps and GetStaticPaths in lotDetails:
const LotDetails = (props:any) => {
const dispatch=useDispatch();
console.log(props)
const lotCount=1;
const addLots=()=>{
dispatch(AddCustomerLot({...props,lotCount:lotCount}))
}
return (
<>
<div className='container lot-details'>
<div className="row" >
<div className="col-md-6">
<div className="detail-container">
<div className="title-details"><h3>{props.title}</h3></div>
<div className="badge"><FontAwesomeIcon icon={faStar}/><span>{props.rate}</span></div>
<div className="inventory">
Inventory: <span className="count">{props.count}</span>
</div>
<div className="description-details">{props.description}</div>
<div className="price">Price: <span className="price-number">{props.price}$</span> </div>
<button className="btn btn-regist" onClick={addLots}>Add to shopping basket</button>
</div>
</div>
<div className="col-md-6"><img src={props.image} alt="" /></div>
</div>
</div>
</>
)
}
export const getStaticPaths:GetStaticPaths=async(context:any)=>{
const response= await axios.get("https://fakestoreapi.com/products")
const paths=response.data.map((el:any)=>({params:{id:el.id.toString()}}))
console.log(paths)
return{
paths,
fallback:'blocking'
}
}
export const getStaticProps:GetStaticProps=async(context:any)=>{
return{
props:
{
//recieve props
id:context.query.id,
title:context.query.title,
image:context.query.image,
description:context.query.description,
rate:context.query.rate,
count:context.query.count,
price:context.query.price
}
}
}
export default LotDetails;
when I deleted getStaticProps and getStaticPaths, the link worked! So I receive that link works perfectly and the problem is in getStaticProps and getStaticPaths. Of course I don't want to use getServerSideProps.
Update
According to julio's suggestion I changed pathName, and I also changed context.query to context.params.id:
Items:
<Link href={{pathname:`/lotDetails/${el.id}`,query:{id:JSON.stringify(el.id),title:el.title,image:el.image,description:el.description.toString(),rate:el.rating.rate,count:el.rating.count,price:el.price},}} as={`/lotDetails/${el.id.toString()}`}>
<div className="lot">
<div className="img-container">
<img src={el.image}/>
</div>
<div className="title">
{el.title}
</div>
<div className="price">
<span className="price-title">Price:</span>
<span>{el.price}</span>
</div>
</div>
</Link>
lotDetails:
return (
<>
<div className='container lot-details'>
<div className="row" >
<div className="col-md-6">
//I removed all section which used props and querys using comments
{/* <div className="detail-container">
<div className="title-details"><h3>{props.title}</h3></div>
<div className="badge"><FontAwesomeIcon icon={faStar}/><span>{props.rate}</span></div>
<div className="inventory">
Inventory: <span className="count">{props.count}</span>
</div>
<div className="description-details">{props.description}</div>
<div className="price">Price: <span className="price-number">{props.price}$</span> </div>
<button className="btn btn-regist" onClick={addLots}>Add to shopping basket</button>
</div> */}
</div>
{/* <div className="col-md-6"><img src={props.image} alt="" /></div> */}
</div>
</div>
</>
)
}
export const getStaticPaths:GetStaticPaths=async(context:any)=>{
const response= await axios.get("https://fakestoreapi.com/products")
const paths=response.data.map((el:any)=>({params:{id:el.id.toString()}}))
console.log(paths)
return{
paths,
fallback:'blocking'
}
}
export const getStaticProps:GetStaticProps=async(context:any)=>{
return{
props:
{
id:context.params.id,
// title:context.query.title,
// image:context.query.image,
// description:context.query.description,
// rate:context.query.rate,
// count:context.query.count,
// price:context.query.price
}
}
}
Finally, I solved problem in two steps:
1-I'm using google chrome browser, so I configured chrome and added my localhost port:
I used this link: chrome://inspect/, clicked configure button and added my localhost port(in my case localhost:3000)
2-I added this code to lotDetails page(the page which I used axios)
axios.defaults.httpsAgent=new https.Agent({
rejectUnauthorized:false,
})
don't forget to import:
import https from "https"
Now It's working.

Use same usestate hook for multiple icons

I have a two buttons in my react project (material ui icons) which are lowerarrow(both) and i made a use state and function to change upper arrow to lower arrow when it is clicked but i dont know how to use the same state for my another icon too, maybe using some id or something i dont know , right now i put {iconstate} in both the icons so both the icons are changing together i am trying to figure out how to change them individually without making new state and function here is my code :-
JSX:-
import React , {useState} from 'react';
import Weather_leftpanecss from './Weather_leftpane.module.css'
import KeyboardArrowDownIcon from '#mui/icons-material/KeyboardArrowDown';
import KeyboardArrowUpIcon from '#mui/icons-material/KeyboardArrowUp';
export default function Weather_leftpane() {
const [iconstate, seticonstate] = useState(<KeyboardArrowDownIcon/>)
const [valuestate, setvaluestate] = useState(true)
const togglearrow = ()=>{
if(valuestate==true){
seticonstate(<KeyboardArrowUpIcon/>)
setvaluestate(false)
}
else{
seticonstate(<KeyboardArrowDownIcon/>)
setvaluestate(true)
}
}
return <div>
<div className={Weather_leftpanecss.main}>
<div id={Weather_leftpanecss.item_1}>Weather</div>
<div id={Weather_leftpanecss.item_2}>
<input type="text" placeholder='Search for city..' />
</div>
<div id={Weather_leftpanecss.item_3}>
<div className={Weather_leftpanecss.item_3_content} id="item_3_1">
Cities
</div>
<div className={Weather_leftpanecss.item_3_content} id="item_3_2" onClick={togglearrow} >
{iconstate}
</div>
</div>
<div id={Weather_leftpanecss.item_4}>
<div className={Weather_leftpanecss.item_4_content} id="item_4_1">
Settings
</div>
<div className={Weather_leftpanecss.item_4_content} id="item_4_2" onClick={togglearrow}>
{iconstate}
</div>
</div>
</div>
</div>;
}
css:-
.App {
font-family: sans-serif;
text-align: center;
}
(not the real css ,just added it because i have included it everywhere in my code with module)
Here you need to save the selected Id in the state.
import React , {useState} from 'react';
import Weather_leftpanecss from './Weather_leftpane.module.css'
import KeyboardArrowDownIcon from '#mui/icons-material/KeyboardArrowDown';
import KeyboardArrowUpIcon from '#mui/icons-material/KeyboardArrowUp';
export default function Weather_leftpane() {
const [valuestate, setvaluestate] = useState(true)
const [id, setId] = useState(null);
const togglearrow = (val)=>{
if(valuestate==true){
setvaluestate(false)
}else{
setvaluestate(true)
}
setId(val);
}
return <div>
<div className={Weather_leftpanecss.main}>
<div id={Weather_leftpanecss.item_1}>Weather</div>
<div id={Weather_leftpanecss.item_2}>
<input type="text" placeholder='Search for city..' />
</div>
<div id={Weather_leftpanecss.item_3}>
<div className={Weather_leftpanecss.item_3_content} id="item_3_1">
Cities
</div>
<div className={Weather_leftpanecss.item_3_content} id="item_3_2" onClick={() => togglearrow('item_3_2')} >
{valuestate && id == 'item_3_2' ? KeyboardArrowUpIcon : KeyboardArrowDownIcon }
</div>
</div>
<div id={Weather_leftpanecss.item_4}>
<div className={Weather_leftpanecss.item_4_content} id="item_4_1">
Settings
</div>
<div className={Weather_leftpanecss.item_4_content} id="item_4_2" onClick={() => togglearrow('item_4_1')}>
{valuestate && id == 'item_4_1' ? KeyboardArrowUpIcon : KeyboardArrowDownIcon }
</div>
</div>
</div>
</div>;
}
Here you can use one state to achieve that, saving in one state the status of both buttons, which one is clicked or not and render the icon based on that status.
the toggleArrow function gets the itemId and uses it to set the updated value of the button. We use !prevState[itemId] since if it is false it will become true and vise versa.
I took the liberty of giving the state a more informative name than a generic name.
import React, { useState } from "react";
import Weather_leftpanecss from "./Weather_leftpane.module.css";
import KeyboardArrowDownIcon from "#mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "#mui/icons-material/KeyboardArrowUp";
export default function Weather_leftpane() {
const [clickedButtons, setClickedButtons] = useState({
item_3_2: false,
item_4_2: false
});
const toggleArrow = (itemId) => {
setClickedButtons((prevState) => ({
...prevState,
[itemId]: !prevState[itemId]
}));
};
return (
<div>
<div className={Weather_leftpanecss.main}>
<div id={Weather_leftpanecss.item_1}>Weather</div>
<div id={Weather_leftpanecss.item_2}>
<input type="text" placeholder="Search for city.." />
</div>
<div id={Weather_leftpanecss.item_3}>
<div className={Weather_leftpanecss.item_3_content} id="item_3_1">
Cities
</div>
<div
className={Weather_leftpanecss.item_3_content}
id="item_3_2"
onClick={() => toggleArrow("item_3_2")}
>
{clickedButtons["item_3_2"] ? (
<KeyboardArrowUpIcon />
) : (
<KeyboardArrowDownIcon />
)}
</div>
</div>
<div id={Weather_leftpanecss.item_4}>
<div className={Weather_leftpanecss.item_4_content} id="item_4_1">
Settings
</div>
<div
className={Weather_leftpanecss.item_4_content}
id="item_4_2"
onClick={() => toggleArrow("item_4_2")}
>
{clickedButtons["item_4_2"] ? (
<KeyboardArrowUpIcon />
) : (
<KeyboardArrowDownIcon />
)}
</div>
</div>
</div>
</div>
);
}

How to open dynamic modal with react js

I am trying to convert the HTML/Javascript modal to React js.
In Reactjs, I just want to open the modal whenever the user clicks the View Project button.
I have created a parent component (Portfolio Screen) and a child component (Portfolio Modal). The data I have given to the child component is working fine but the modal opens the first time only and then does not open. Another problem is that the data does not load even when the modal is opened the first time.
Codesandbox link is here.
https://codesandbox.io/s/reverent-leftpad-lh7dl?file=/src/App.js&resolutionWidth=683&resolutionHeight=675
I have also shared the React code below.
For HTML/JavaScript code, here is the question I have asked before.
How to populate data in a modal Popup using react js. Maybe with hooks
Parent Component
import React, { useState } from 'react';
import '../assets/css/portfolio.scss';
import PortfolioModal from '../components/PortfolioModal';
import portfolioItems from '../data/portfolio';
const PortfolioScreen = () => {
const [portfolio, setportfolio] = useState({ data: null, show: false });
const Item = (portfolioItem) => {
setportfolio({
data: portfolioItem,
show: true,
});
};
return (
<>
<section className='portfolio-section sec-padding'>
<div className='container'>
<div className='row'>
<div className='section-title'>
<h2>Recent Work</h2>
</div>
</div>
<div className='row'>
{portfolioItems.map((portfolioItem) => (
<div className='portfolio-item' key={portfolioItem._id}>
<div className='portfolio-item-thumbnail'>
<img src={portfolioItem.image} alt='portfolio item thumb' />
<h3 className='portfolio-item-title'>
{portfolioItem.title}
</h3>
<button
onClick={() => Item(portfolioItem)}
type='button'
className='btn view-project-btn'>
View Project
</button>
</div>
</div>
))}
<PortfolioModal portfolioData={portfolio} show={portfolio.show} />
</div>
</div>
</section>
</>
);
};
export default PortfolioScreen;
Child Component
import React, { useState, useEffect } from 'react';
import { NavLink } from 'react-router-dom';
const PortfolioModal = ({ portfolioData, show }) => {
const portfolioItem = portfolioData;
const [openModal, setopenModal] = useState({ showState: false });
useEffect(() => {
setopenModal({
showState: show,
});
}, [show]);
return (
<>
<div
className={`portfolio-popup ${
openModal.showState === true ? 'open' : ''
}`}>
<div className='pp-inner'>
<div className='pp-content'>
<div className='pp-header'>
<button
className='btn pp-close'
onClick={() =>
setopenModal({
showState: false,
})
}>
<i className='fas fa-times pp-close'></i>
</button>
<div className='pp-thumbnail'>
<img src={portfolioItem.image} alt={`${portfolioItem.title}`} />
</div>
<h3 className='portfolio-item-title'>{portfolioItem.title}</h3>
</div>
<div className='pp-body'>
<div className='portfolio-item-details'>
<div className='description'>
<p>{portfolioItem.description}</p>
</div>
<div className='general-info'>
<ul>
<li>
Created - <span>{portfolioItem.creatDate}</span>
</li>
<li>
Technology Used -
<span>{portfolioItem.technologyUsed}</span>
</li>
<li>
Role - <span>{portfolioItem.Role}</span>
</li>
<li>
View Live -
<span>
<NavLink to='#' target='_blank'>
{portfolioItem.domain}
</NavLink>
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</>
);
};
export default PortfolioModal;
You don't have to use one useState hook to hold all your states. You can and I think you should break them up. In the PortfolioScreen component
const [data, setData] = useState(null);
const [show, setShow] = useState(false);
I changed the function Item that is used to set the active portfolio item to toggleItem and changed it's implementation
const toggleItem = (portfolioItem) => {
setData(portfolioItem);
setVisible(portfolioItem !== null);
};
You should use conditional rendering on the PortfolioModal, so you won't need to pass a show prop to it, and you'll pass a closeModal prop to close the PortfolioModal when clicked
{visible === true && data !== null && (
<PortfolioModal
data={data}
closeModal={() => toggleItem()} // Pass nothing here so the default value will be null and the modal reset
/>
)}
Then in the PortfolioModal component, you expect two props, data and a closeModal function
const PortfolioModal = ({ data, closeModal }) => {
And the close button can be like
<button className="btn pp-close" onClick={closeModal}>
...

Button Click to Render Div

I want to click the button and render its corresponding div. Should I add the the div's info that I want to render to the state?
I'm sure there's a few different ways to solve this but I want to do it the React way and maybe as a function component?
Updated
export default function About(props) (
const [isHidden, setIsHidden] = useState(true);
const handleClick = () => {
setIsHidden(!isHidden);
};
return (
<div className="row justify-content-md-center">
<div className="col-auto">
<CustomButton onClick={handleClick}>Website Develpment</CustomButton>
</div>
<div className="col-auto">
<CustomButton onClick={handleClick}>Wordpress Develpment</CustomButton>
</div>
<div className="col-auto">
<CustomButton onClick={handleClick}>Ecommerce Development</CustomButton>
</div>
</div>
<div className="row">
<div className="col-md-4">column 1</div>
<div className="col-md-4">column 2</div>
<div className="col-md-4">column 3</div>
</div>
);
)
You can store an ID as a string state variable, and set that variable on button press.
Then use ConditionalRendering to only display the div with the matching ID.
const {useState} = React;
function About(props) {
const [visibleItem, setVisibleItem] = useState('');
return (
<div>
<button onClick={() => setVisibleItem("website")}>
Show Website Develpment
</button>
<button onClick={() => setVisibleItem("wordpress")}>
Show Wordpress Develpment
</button>
<button onClick={() => setVisibleItem("ecommerce")}>
Show Ecommerce Development
</button>
{visibleItem === "website" &&
<div>
<h2>Wordpress Development</h2>
<p>Info about Wordpress and all the things I can do with it</p>
</div>
}
{visibleItem === "wordpress" &&
<div>
<h2>Ecommerce Development</h2>
<p>I can do eccomerce things too</p>
</div>
}
{visibleItem === "ecommerce" &&
<div>
<h2>Website Development</h2>
<p>Info about Webdev</p>
</div>
}
</div>
);
}
ReactDOM.render(
<About/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
If the sections were much bigger then I'd recommend splitting them out into separate components, or maybe doing an if or switch statement to select between them before the return, but the above snippet is a pattern I have used often with react.
You can create two states one holding array of button info to minimize repetition of code and another state to track the column clicked.
import React, { useState } from "react";
export default function About(props) {
const [colNum, setColNum] = useState('');
const [btnNames] = useState([
{
colId: 1,
name: "Website Develpment"
},
{
colId: 2,
name: "Wordpress Develpment"
},
{
colId: 3,
name: "Ecommerce Develpment"
}
]);
const handleClick = (id) => {
setColNum(id);
};
return (
<>
<div className="row justify-content-md-center">
{btnNames.map(element => (
<div className="col-auto" key={element.colId}>
<CustomButton onClick={()=> handleClick(element.colId)}>{element.name}</CustomButton>
</div>
))}
</div>
{colNum !== '' ? (<div className="row">
<div className="col-md-4">column {colNum}</div>
</div>) : null }
</>
);
}
So you can define showing value for each section in state, which initial should be false. Then we can handle this state with a function where built-in JS tools can be used (Object.entries, Object.fromEntries and map). The element will be displayed, the value of which will be true, and the rest will automatically become false. More details can be found here: https://codesandbox.io/s/happy-sea-nckmw?file=/src/App.js
import React, { useState } from "react";
import "./styles.css";
import styles from "./TestStyles.module.css";
import CustomButton from "./CustomButton";
export default function App() {
const [showDiv, setShowDiv] = useState({
web: false,
wordpress: false,
ecommerce: false
});
const showDivHandler = (val) => {
const newState = Object.fromEntries(
Object.entries(showDiv).map(([key, value]) => [key, (value = false)])
);
setShowDiv({
...newState,
[val]: !showDiv[val]
});
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div className={styles.Section}>
<div className="col-auto">
<CustomButton clicked={() => showDivHandler("web")}>
Website Develpment
</CustomButton>
</div>
<div className="col-auto">
<CustomButton clicked={() => showDivHandler("wordpress")}>
Wordpress Develpment
</CustomButton>
</div>
<div className="col-auto">
<CustomButton clicked={() => showDivHandler("ecommerce")}>
Ecommerce Development
</CustomButton>
</div>
</div>
<div className={styles.Section} style={{marginTop: 20}}>
{showDiv.web && <div className={styles.Content}>column 1</div>}
{showDiv.wordpress && <div className={styles.Content}>column 2</div>}
{showDiv.ecommerce && <div className={styles.Content}>column 3</div>}
</div>
</div>
);
}
The custom button can look like this:
import React from "react";
const button = (props) => (
<button
onClick={props.clicked}
//some other props if need it(e.g. styles)
>
{props.children}
</button>
);
export default button;
This is how I solved it. Thanks for your help!
export default function About() {
const [visibleItem, setVisibleItem] = useState(1);
const [priceItems] = useState([
{
id: 1,
name: "website",
},
{
id: 2,
name: "wordpress",
},
{
id: 3,
name: "ecommerce",
},
]);
const handleClick = (id) => {
setVisibleItem(id);
};
return (
<div className="container-fluid pricing-wrapper">
<div className="row">
<div className="col">
<h1>Pricing</h1>
</div>
</div>
<div className="row">
<div className="col">
<p>Innovation that empowers your team while also reducing risk!</p>
<div className="seperator"></div>
</div>
</div>
<div className="row justify-content-md-center">
<div className="row justify-content-md-center">
{priceItems.map((item) => (
<div className="col-auto">
<CustomButton onClick={() => setVisibleItem(item.id)}>
{item.name}
</CustomButton>
</div>
))}
</div>
</div>
{priceItems
.filter((item) => item.id === visibleItem)
.map((item) => (
<PriceItem item={item} />
))}
</div>
);
}

Resources