Hello, I've recently made a react component, and my Material UI tabs aren't switching properly, I've attached a video for you to see the issue. If I put the tabs manually, it all works just fine.
Video: https://streamable.com/heugq4
My component:
import * as React from 'react';
import PropTypes from 'prop-types';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import NamePanel from "./NamePanel.jsx";
import {PayClient} from "../Offchain.js";
import * as ViteConnect from "../ViteConnect.js"
import {useEffect} from "react";
function TabPanel(props) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box sx={{ p: 3 }}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
TabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.number.isRequired,
value: PropTypes.number.isRequired,
};
function a11yProps(index) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
export default function ManageNameTabs() {
const [value, setValue] = React.useState(0);
const [tabs, setTabs] = React.useState('e');
const [tabPanels, setTabPanels] = React.useState([]);
const [namesArray, setNamesArray] = React.useState([]);
useEffect(() => {
async function run() {
const connectedAddress = ViteConnect.getConnectedAddress()
const names = await PayClient.getNamesByAddress(connectedAddress);
let tabs = [];
let tabPanels = [];
let currentIndex = 0;
for (const name of names) {
console.log(name)
tabPanels.push(
<TabPanel value={value} index={currentIndex} key={name.nameId} >
<NamePanel name={name.name} nameId={name.nameId} owner={connectedAddress}
isVerified={name.isTrusted} key={name.nameId}/>
</TabPanel>
)
tabs.push(<Tab label={name.name + ".vinu"} {...a11yProps(currentIndex)} key={name.nameId}/>)
currentIndex++;
}
setTabPanels(tabPanels);
setTabs(tabs);
}
run()
}, [])
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box sx={{ width: '100%' }} component="div">
<Box sx={{ borderBottom: 1, borderColor: 'divider', maxWidth: { xs: 320, sm: 480, md: 600, lg: 900}, minWidth: {xs: 200, sm: 300, md: 400, lg: 800}}} component="div">
<Tabs value={value} onChange={handleChange} aria-label="basic tabs example" variant="scrollable" scrollButtons="auto">
{tabs}
</Tabs>
</Box>
{tabPanels}
</Box>
);
}
Top comments (1)
One possible reason your tabs aren't switching properly is that you are setting the
valueof theTabscomponent andTabPanelcomponents outside of their control. Thevalueprop of theTabsandTabPanelcomponents should be controlled by the parent component, and updated when the user clicks on a tab.In your code, you are using a
useStatehook to store thevalueof theTabscomponent, but you are not updating this value when the user clicks on a tab. You should update thevaluestate when thehandleChangefunction is called, like this:Then, pass the
valuestate to thevalueprop of theTabsandTabPanelcomponents, like this:This should allow the
TabsandTabPanelcomponents to control their ownvalueprop, and switch between tabs properly.I'm an experimental help bot that leverages ChatGPT. As such, the answers I provide may be incorrect, incomplete, or even nonsensical. I am not associated with OpenAI.
Please reply to my comment(s) with your own corrections and feedback.