Simple tabs in ReactJS using components - reactjs

I am new to React.js, I know basic stuff like state, components, but I need to:
Create a MyTabsComponent to be used like this:
<MyTabsComponent>
<div title={"Section title 1"}>Content of section 1</div>
<div title={"Section title 2"}>Content of section 2</div>
<div title={"Section title 3"}>Content of section 2</div>
<div title={"Section title 4"}>Content of section 2</div>
<div title={"Section title 5"}>Content of section 2</div>
.
.
.
.
.and so on..............
.
.
.
.
.
</MyTabsComponent>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
See visual
The above code should render like this:
<div class="tabs">
<button class="btn-active">Section title 1</button>
<button class="btn">Section title 2</button>
<button class="btn">Section title 3</button>
<button class="btn">Section title 4</button>
<!--
.
.
.
.
.
.
and so on..........
-->
<div class="view">
Content of section 1
</div>
</div>
What I've tried:
import React,{useState} from "react";
const MyTabsComponent = () => {
const [title,setTitle] = useState(['Section 1','Section 2','Section 3']);
const [ct,setCt] = useState(null);
return (
<div className="tabs">
<TabButtons tabName={title} tabCt={setCt} />
<div class="view">
Content : {ct}
</div>
</div>
);
};
const TabButtons = (props) => {
return (
<>
{
props.tabName.map((item,i)=>
<button onClick={()=>props.tabCt(i)} className="btn">{item}</button>
)
}
</>
);
};
export default MyTabsComponent;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I don't know how to do this for any number of tabs. Rest I can handle-- CSS, onClick events I understand well, as I know JS well.
EDIT: I found an article on Compound Components https://blog.logrocket.com/understanding-react-compound-components/
and they say:
import React, { useState, createContext, useContext } from "react";
//the name of this context will be DataContext
const DataContext = createContext({});
function Tab({ id, children }) {
//extract the 'setActiveTabID` method from the DataContext state.
const [, setActiveTabID] = useContext(DataContext);
return (
<div>
<div onClick={() => setActiveTabID(id)}>{children}</div>
</div>
);
}
function TabPanel({ whenActive, children }) {
//get the 'activeTabID' state from DataContext.
const [activeTabID] = useContext(DataContext);
return <div>{activeTabID === whenActive ? children : null}</div>;
}
function TabSwitcher(props) {
const [activeTabID, setActiveTabID] = useState("a");
//since this component will provide data to the child components, we will use DataContext.Provider
return (
<DataContext.Provider value={[activeTabID, setActiveTabID]}>
{props.children}
</DataContext.Provider>
);
}
export default TabSwitcher;
export { Tab, TabPanel };
And to use:
import TabSwitcher, { Tab, TabPanel } from "./TabSwitcher";
function App() {
return (
<div className="App">
<h1>TabSwitcher with Compound Components</h1>
<TabSwitcher>
<Tab id="a">
<button>a</button>
</Tab>
<Tab id="b">
<button>b</button>
</Tab>
<TabPanel whenActive="a">
<div>a panel</div>
</TabPanel>
<TabPanel whenActive="b">
<div>b panel</div>
</TabPanel>
</TabSwitcher>
</div>
);
}
export default App;
The problem is: they are using
TabPanel
as a container whereas I want a <div>

UPDATED
Here is the latest implementation for you
function TabController({ children }) {
if (!children || children.length === 0) {
return null
}
const [currentTab, setCurrentTab] = React.useState(children[0])
return (
<>
{children.map((child) => (
<button key={child.title} onClick={() => setCurrentTab(child)}>
{child.props.title}
</button>
))}
<div className="view">{currentTab.props.children}</div>
</>
)
}
This is how we use it
<TabController>
<div title={'Section title 1'}>Content of section 1</div>
<div title={'Section title 2'}>Content of section 2</div>
<div title={'Section title 3'}>Content of section 3</div>
<div title={'Section title 4'}>Content of section 4</div>
<div title={'Section title 5'}>Content of section 5</div>
</TabController>
OLD ANSWER
I tried to create a simple component for you. You can implement actual data for TAB_DATA and pass it into your MyTabsComponent as props
//I mocked TAB_DATA here for testing purpose
const TAB_DATA = [
{
title: 'Section 1',
content: 'Content 1',
},
{
title: 'Section 2',
content: 'Content 2',
},
{
title: 'Section 3',
content: 'Content 3',
},
]
const MyTabsComponent = () => {
const [ct, setCt] = useState(TAB_DATA[0].content) //set the first tab data as default
return (
<div className="tabs">
{TAB_DATA.map((tab) => (
<button
onClick={() => {
setCt(tab.content)
}}
>
{tab.title}
</button>
))}
<div className="view">{ct}</div>
</div>
)
}

If you want to create a component that has nested elements of an unknown number or type, then you need to make use of the children prop. This is not something you have to define, but represents the child elements of the component when it is called.
Simply nest any number of components or elements between your component tags, and in MyTabsComponent pull out the props and put the props.children inside your return statement where you'd like them to go.
For your example, I have elevated the state ct and title to the parent component of MyTabsComponent, and given that state directly to the rendered buttons. I also pass the ct to the MyTabsComponent so it can display its content.
MyTabsComponent
const MyTabsComponent = (props) => {
return (
<div className="tabs">
{props.children}
<div class="view">
Content : {props.ct}
</div>
</div>
);
};
The parent of MyTabsComponent
import React, { useState } from 'react'
const Main = () => {
const [title, setTitle] = useState(['Section 1','Section 2','Section 3']);
const [ct, setCt] = useState(null);
return (
<MyTabsComponent ct={ct}>
{title.map((item, i) =>
<button onClick={() => setCt(i)} className="btn">{item}</button>
)}
</MyTabsComponent>
)
}

Related

React change css style of a div in another component by button clicking in another component

on my Project I have a banner on top of my site with 2 buttons. when I click the button profile I want it to change the css style of a div in another component.
this is my code for the banner:
import Profile from "./Profile";
function Banner() {
const invis=false;
return (
<div className="banner">
<span className="bannerbtnsettings">
<button className="btnbannersettings">Settings</button>
</span>
<span className="bannerbtnprofile">
<button className="btnbannerprofile" onClick={Profile.changeStyle}>Profile</button>
</span>
</div>
);
}
export default Banner;
this is my code for the div in the other component:
import "../index.css";
import React, { useState } from "react";
const Profile = () => {
const [style, setStyle] = useState("profile-hidden");
const changeStyle = () => {
console.log("you just clicked");
setStyle("profile-displayed");
};
return (
<div>
<div className={style}> hellllo</div>
</div>
);
};
export default Profile;
I can only find information about this with parent-child components.
They said I should use a usestate import but I can't seem to get it working. what's the proper way to do this?
All you need is lift your state to parent component, if you have a long trip to your common ancestor you can try to use a context. Attached a working example. Hope it helps!
const Banner = ({ onClickHandler }) => {
return (
<div className="banner">
<span className="bannerbtnsettings">
<button className="btnbannersettings">Settings</button>
</span>
<span className="bannerbtnprofile">
<button className="btnbannerprofile" onClick={() => onClickHandler()}>Profile</button>
</span>
</div>
)}
const Profile = ({ style }) => {
return (
<div>
<div className={style}>I'm your profile :)</div>
</div>
);
};
const App = () => {
// We lift the state
const [style, setStyle] = React.useState("profile-hidden");
const profileHandler = () => {
setStyle(style === 'profile-hidden'
? 'profile-displayed'
: 'profile-hidden')
}
return(
<div>
<Banner onClickHandler={profileHandler} />
<Profile style={style} />
</div>
)
}
// Render
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App />
);
.profile-hidden {
display: none;
}
.profile-displayed {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<div id="root"></div>
You cannot use this syntax for React Components COMPONENT.method
, in your case onClick={Profile.changeStyle} !
Instead you should make Banner parent component and use Profile component as child inside it or vise versa !
then You should pass the state style as props so then you will be able to use its value.
your code should look like this :
function Banner() {
const [style, setStyle] = useState("profile-hidden");
const changeStyle = () => {
console.log("you just clicked");
setStyle("profile-displayed");
};
return (
<div className="banner">
<span className="bannerbtnsettings">
<button className="btnbannersettings">Settings</button>
</span>
<span className="bannerbtnprofile">
<button className="btnbannerprofile" onClick={changeStyle}>Profile</button>
</span>
<Profile style={style} />
</div>
);
}
export default Banner;
and your Profile component :
const Profile = (props) => {
return (
<div>
<div className={props.style}> hellllo</div>
</div>
)
}

How can I create Single Page

How can I pass map items (title, category and images) in my id.jsx file.
Basically, I just want to create a single page for my projects. But I can only access post ID. I don't know how to pass other data items.
'Projects folder'
[id].js
import { useRouter } from "next/router";
const Details = () => {
const router = useRouter();
return <div>Post #{router.query.id}
// Single Project Title = {project.title} (like this)
</div>;
};
export default Details;
index.js
import { MyProjects } from "./MyProjects";
const Projects = () => {
const [projects, setProjects] = useState(MyProjects);
{projects.map((project) => (
<Link
href={"/projects/" + project.id}
key={project.id}
passHref={true}
>
<div className="project__item">
<div className="project__image">
<Image src={project.image} alt="project" />
</div>
<div className="project_info">
<h5>{project.category}</h5>
<h3>{project.title}</h3>
</div>
</div>
</Link>
))}
If I understand your question correctly, you want to send some "state" along with the route transition. This can be accomplished using an href object with the "state" on the query property, and the as prop to hide the query string.
Example:
{projects.map((project) => (
<Link
key={project.id}
href={{
pathname: "/projects/" + project.id,
query: {
id: project.id,
category: project.category,
title: project.title
}
}}
passHref={true}
as={"/projects/" + project.id}
>
<div className="project__item">
<div className="project__image">
<Image src={project.image} alt="project" />
</div>
<div className="project_info">
<h5>{project.category}</h5>
<h3>{project.title}</h3>
</div>
</div>
</Link>
))}
...
const Details = () => {
const router = useRouter();
return (
<div>
<div>Post #{router.query.id}</div>
<div>Title {router.query.title}</div>
<div>Category {router.query.category}</div>
</div>
);
};

Simple tabs component in ReactJS

I am new to React.js, I know basic stuff like state, components, but I need to:
Create a MyTabsComponent to be used like this:
<MyTabsComponent>
<div title={"Section title 1"}>Content of section 1</div>
<div title={"Section title 2"}>Content of section 2</div>
<div title={"Section title 3"}>Content of section 2</div>
<div title={"Section title 4"}>Content of section 2</div>
<div title={"Section title 5"}>Content of section 2</div>
.
.
.
.
.and so on..............
.
.
.
.
.
</MyTabsComponent>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
See visual
The above code should render like this:
<div class="tabs">
<button class="btn-active">Section title 1</button>
<button class="btn">Section title 2</button>
<button class="btn">Section title 3</button>
<button class="btn">Section title 4</button>
<!--
.
.
.
.
.
.
and so on..........
-->
<div class="view">
Content of section 1
</div>
</div>
What I've tried:
import React,{useState} from "react";
const MyTabsComponent = () => {
const [title,setTitle] = useState(['Section 1','Section 2','Section 3']);
const [ct,setCt] = useState(null);
return (
<div className="tabs">
<TabButtons tabName={title} tabCt={setCt} />
<div class="view">
Content : {ct}
</div>
</div>
);
};
const TabButtons = (props) => {
return (
<>
{
props.tabName.map((item,i)=>
<button onClick={()=>props.tabCt(i)} className="btn">{item}</button>
)
}
</>
);
};
export default MyTabsComponent;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I don't know how to do this for any number of tabs. Rest I can handle-- CSS, onClick events I understand well, as I know JS well.
EDIT: I found an article on Compound Components https://blog.logrocket.com/understanding-react-compound-components/
and they say:
import React, { useState, createContext, useContext } from "react";
//the name of this context will be DataContext
const DataContext = createContext({});
function Tab({ id, children }) {
//extract the 'setActiveTabID` method from the DataContext state.
const [, setActiveTabID] = useContext(DataContext);
return (
<div>
<div onClick={() => setActiveTabID(id)}>{children}</div>
</div>
);
}
function TabPanel({ whenActive, children }) {
//get the 'activeTabID' state from DataContext.
const [activeTabID] = useContext(DataContext);
return <div>{activeTabID === whenActive ? children : null}</div>;
}
function TabSwitcher(props) {
const [activeTabID, setActiveTabID] = useState("a");
//since this component will provide data to the child components, we will use DataContext.Provider
return (
<DataContext.Provider value={[activeTabID, setActiveTabID]}>
{props.children}
</DataContext.Provider>
);
}
export default TabSwitcher;
export { Tab, TabPanel };
And to use:
import TabSwitcher, { Tab, TabPanel } from "./TabSwitcher";
function App() {
return (
<div className="App">
<h1>TabSwitcher with Compound Components</h1>
<TabSwitcher>
<Tab id="a">
<button>a</button>
</Tab>
<Tab id="b">
<button>b</button>
</Tab>
<TabPanel whenActive="a">
<div>a panel</div>
</TabPanel>
<TabPanel whenActive="b">
<div>b panel</div>
</TabPanel>
</TabSwitcher>
</div>
);
}
export default App;
The problem is: they are using
TabPanel
as a container whereas I want a <div>
EDIT: Please see the link Alexander posted in the comment for the best practices in accessibility for tabs like this, or this link which has an example https://www.w3.org/TR/wai-aria-practices-1.1/examples/tabs/tabs-2/tabs.html
My post here solves the problem in terms of "making this work", but you should really be aiming for proper tabs and tabpanels to make this accessible.
ORIGINAL ANSWER:
The problem is: they are using TabPanel as a container whereas I want a <div>
When you say "I want a <div>", do you mean that you want to write div in your code, or that you want a div in the DOM?
The example you found, where they use TabPanel, does render a div to the DOM, because TabPanel returns a div.
One thing that jumps out is you don't need to store your Titles in state, because they are never changing.
To do what you're trying to do, I'd probably go like this:
import React,{useState} from "react";
const tabData = [
{title: "Section title 1", content: "Content of section 1"}
{title: "Section title 2", content: "Content of section 2"}
{title: "Section title 3", content: "Content of section 3"}
]
const MyTabsComponent = () => {
const [ct,setCt] = useState(null);
return (
<div className="tabs">
{tabData.map(({title}, i) => (
<TabButton
title={title}
isActive={i === ct}
onClick={()=>props.tabCt(i)} />
)}
<div class="view">
Content : {tabData[ct].content}
</div>
</div>
);
};
const TabButton = ({ title, isActive, onClick }) => {
return (
<button onClick={onClick} className={isActive ? "active-btn" : "btn"}>
{title}
</button>
);
};
export default MyTabsComponent;
From what I can tell, your question is how to render any number of tabs? It seems that your snippet already does this. However, you did have one too many parentheses, or one too few depending on how you look at it.
import React,{useState} from "react";
const myTabs = ['Section 1','Section 2','Section 3'];
const MyTabsComponent = () => {
const [ct,setCt] = useState(null);
return (
<div className="tabs">
<TabButtons tabCt={setCt} />
<div>Content: {ct}</div>
</div>
);
};
const TabButtons = (props) => {
return (
<>
{myTabs.map((item,i) => (
<button onClick={()=>props.tabCt(i)} className="btn">
{item}
</button>
)}
</>
);
};
export default MyTabsComponent;
This should work. You could have 1 or 1000 tabs in myTabs and it would render all of them.

adding and removing a classList in react js

I am using functional component in react js , in the below code
the class right-panel-active is not being added / is undefined. Someone help to enable the class be added when the button is toggled
import React from 'react';
import './style.css';
import {
Modal,
DropdownMenu
} from '../MaterialUI';
/**
* #author
* #function Header
**/
const Header = (props) => {
const container = () => {
document.getElementById('container');
}
const signUpButton = () => {
container.classList.add('right-panel-active');
};
const signInButton = () => {
container.classList.remove('right-panel-active');
};
return (
<div className="header">
<div className="container" id="container">
<button className="ghost" id="signIn" onClick={signInButton} >Sign In</button>
</div>
<div className="overlay-panel overlay-right">
<p>Enter your personal details and start journey with us</p>
<button className="ghost" id="signUp" onClick={signUpButton} >Sign Up</button>
</div>
</div>
)
}
export default Header
You are not utilising any of React's functionality.
Read about state management in React
and Event Handlers in React
const Header = (props) => {
const [isContainerActive, setIsContainerActive] = React.useState(false);
const signUpButton = () => {
setIsContainerActive(false);
};
const signInButton = () => {
setIsContainerActive(true);
};
return (
<div className="header">
<div id="container" className={`container${isContainerActive ? " right-panel-active" : ""}`}>
<button className="ghost" id="signIn" onClick={signInButton}>Sign In</button>
</div>
<div className="overlay-panel overlay-right">
<p>Enter your personal details and start journey with us</p>
<button className="ghost" id="signUp" onClick={signUpButton}>Sign Up</button>
</div>
</div>
);
}
ReactDOM.render(<Header />, document.getElementById("root"));
.header {height: 120px;}
.container {float:left;}
.overlay-right {display: none;background: red;float:right;height:100%;}
.right-panel-active ~ .overlay-right {display: inline-block;}
<div id="root"></div>
<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>
PS: I also recommend https://www.npmjs.com/package/classnames , or the cx library for className management.
I think the best solution for this is to making a state and handle the style by a ternarian
function Welcome(props) {
const {name} = props;
return (
<h1 style={name === 'Sara' ? right-panel-active : right-panel-inactive}>Hello, {name}</h1>
)}
function App() {
return (
<div>
<Welcome name="Sara" />
</div>
);
}
This is the React way of doing,
You have to keep a local state (useState) and track the button click and based on the state change update the class to the container. You shouldn't directly change the DOM.
Click on the button to see the CSS is adding or not.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [isSignUp, setSignUp] = useState(true);
return (
<div id="container" className={isSignUp ? "right-panel-active" : ""}>
<button onClick={() => setSignUp(false)}>SignIn</button>
<button onClick={() => setSignUp(true)}>SignUp</button>
//for testing the change
{isSignUp ? "right-panel-active added" : "right-panel-active removed"}
</div>
);
}
Sample working code - https://codesandbox.io/s/fragrant-http-qo6du?file=/src/App.js
No need to add click event with vanilla js, you could add an React onClick event. You forgot to return the container.
// if you use curly braces you must return the value
const container = () => {
return document.getElementById('container');
};
// or skip the curly braces
const container = () =>
document.getElementById('container');

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