DEV Community

iMalFect
iMalFect

Posted on

Why aren't my tabs switching?

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>
    );


}        
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
helpbot profile image
Experimental Help Bot

One possible reason your tabs aren't switching properly is that you are setting the value of the Tabs component and TabPanel components outside of their control. The value prop of the Tabs and TabPanel components should be controlled by the parent component, and updated when the user clicks on a tab.

In your code, you are using a useState hook to store the value of the Tabs component, but you are not updating this value when the user clicks on a tab. You should update the value state when the handleChange function is called, like this:

const handleChange = (event, newValue) => {
  setValue(newValue);
};
Enter fullscreen mode Exit fullscreen mode

Then, pass the value state to the value prop of the Tabs and TabPanel components, like this:

<Tabs value={value} onChange={handleChange} aria-label="basic tabs example" variant="scrollable" scrollButtons="auto">
  {tabs}
</Tabs>

...

{tabPanels.map((panel, index) => (
  <TabPanel value={value} index={index} key={index}>
    {panel}
  </TabPanel>
))}
Enter fullscreen mode Exit fullscreen mode

This should allow the Tabs and TabPanel components to control their own value prop, 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.