I don't understand why the following error appears.
I'm trying to render {links}, {collapse} in a return function, but it doesn't work.
links and collapse is about opening sub menus.
Thank you for your help.
The error message:
Objects are not valid as a React child (found: object with keys
{$$typeof, type, compare, displayName, muiName}). If you meant to
render a collection of children, use an array instead.
-- Sidebar.js
/*eslint-disable*/
import React from "react";
import classNames from "classnames";
import PropTypes from "prop-types";
import { NavLink } from "react-router-dom";
// #material-ui/core components
import { makeStyles } from "#material-ui/core/styles";
import {
Drawer,
Hidden,
List,
ListItem,
ListItemText,
Icon,
Collapse
} from "#material-ui/core";
import ExpandLess from "#material-ui/icons/ExpandLess";
import ExpandMore from "#material-ui/icons/ExpandMore";
import ListItemLink from "./ListItemLink";
// core components
import AdminNavbarLinks from "components/Navbars/AdminNavbarLinks.js";
import RTLNavbarLinks from "components/Navbars/RTLNavbarLinks.js";
import styles from "assets/jss/material-dashboard-react/components/sidebarStyle.js";
const useStyles = makeStyles(styles);
export default function Sidebar(props) {
const classes = useStyles();
// verifies if routeName is the one active (in browser input)
function activeRoute(routeName) {
return window.location.href.indexOf(routeName) > -1 ? true : false;
}
const { color, logo, image, logoText, routes } = props;
const [open, setOpen] = React.useState(true);
const handleClick = () => {
setOpen(!open);
};
var links = (
<div>
{routes.map((prop, key) => {
return (
<div>
{prop.submenu.length > 0 ? (
<ListItemLink
to={prop.layout + prop.path}
key={prop.id}
menuText={prop.name}
onClick={handleClick}
subOpen={open}
icon={prop.icon}
/>
) : (
<ListItemLink
to={prop.layout + prop.path}
key={prop.id}
menuText={prop.name}
icon={prop.icon}
/>
)}
</div>
);
})}
</div>
);
var collapse = (
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
{routes.map((prop, key) => {
{
prop.submenu.map((sub, index) => {
return (
<ListItemLink
key={sub.id}
to={sub.path}
menuText={sub.name}
icon={sub.icon}
className={classes.nested}
/>
);
});
}
})}
</List>
</Collapse>
);
var brand = (
<div className={classes.logo}>
<a
className={classNames(classes.logoLink, {
[classes.logoLinkRTL]: props.rtlActive
})}
target="_blank"
>
<div className={classes.logoImage}>
<img src={logo} alt="logo" className={classes.img} />
</div>
{logoText}
</a>
</div>
);
return (
<div>
<Hidden mdUp implementation="css">
<Drawer
variant="temporary"
anchor={props.rtlActive ? "left" : "right"}
open={props.open}
classes={{
paper: classNames(classes.drawerPaper, {
[classes.drawerPaperRTL]: props.rtlActive
})
}}
onClose={props.handleDrawerToggle}
ModalProps={{
keepMounted: true // Better open performance on mobile.
}}
>
{brand}
<div className={classes.sidebarWrapper}>
{props.rtlActive ? <RTLNavbarLinks /> : <AdminNavbarLinks />}
<List component="nav" className={classes.list}>
{links}
{collapse}
</List>
</div>
{image !== undefined ? (
<div
className={classes.background}
style={{ backgroundImage: "url(" + image + ")" }}
/>
) : null}
</Drawer>
</Hidden>
<Hidden smDown implementation="css">
<Drawer
anchor={props.rtlActive ? "right" : "left"}
variant="permanent"
open
classes={{
paper: classNames(classes.drawerPaper, {
[classes.drawerPaperRTL]: props.rtlActive
})
}}
>
{brand}
<div className={classes.sidebarWrapper}>
<List component="nav" className={classes.list}>
{links}
{collapse}
</List>
</div>
{image !== undefined ? (
<div
className={classes.background}
style={{ backgroundImage: "url(" + image + ")" }}
/>
) : null}
</Drawer>
</Hidden>
</div>
);
}
Sidebar.propTypes = {
rtlActive: PropTypes.bool,
handleDrawerToggle: PropTypes.func,
bgColor: PropTypes.oneOf(["purple", "blue", "green", "orange", "red"]),
logo: PropTypes.string,
image: PropTypes.string,
logoText: PropTypes.string,
routes: PropTypes.arrayOf(PropTypes.object),
open: PropTypes.bool
};
-- ListItemLink.js
import React from "react";
import { ListItem, ListItemText, ListItemIcon } from "#material-ui/core";
import ExpandLess from "#material-ui/icons/ExpandLess";
import ExpandMore from "#material-ui/icons/ExpandMore";
import { PropTypes } from "prop-types";
import { Link as RouterLink } from "react-router-dom";
function ListItemLink(props) {
const { to, menuText, icon, subOpen, ...other } = props;
return (
<ListItem button component={RouterLink} to={to} {...other}>
<ListItemIcon>{icon}</ListItemIcon>
<ListItemText primary={menuText} />
{subOpen != null ? subOpen ? <ExpandLess /> : <ExpandMore /> : null}
</ListItem>
);
}
ListItemLink.propTypes = {
subOpen: PropTypes.bool,
to: PropTypes.string.isRequired
};
export default ListItemLink;
in collapse, you have two map functions. you should return the second map function.
something like this:
const collapse = (
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
{routes.map((prop, key) => {
return prop.submenu.map((sub, index) => {
return (
<ListItemLink
key={sub.id}
to={sub.path}
menuText={sub.name}
icon={sub.icon}
className={classes.nested}
/>
);
});
})}
</List>
</Collapse>
);
I solved my question as followed:
I guess I returned the wrong object...
<List
{...rest}
className={clsx(classes.root, className)}
>
{pages.map(page => (
<React.Fragment key={page.title}>
<ListItem
className={classes.item}
disableGutters
key={page.title}
onClick={page.submenu.length > 0 ? handleClick : null}
open={page.submenu.length > 0 ? open : null}
>
<Button
activeClassName={classes.active}
className={classes.button}
component={CustomRouterLink}
to={page.href}
>
<div className={classes.icon}>{page.icon}</div>
{page.title}
{page.submenu.length > 0 ? (
open ? (
<ExpandLess />
) : (
<ExpandMore />
)
) : null}
</Button>
</ListItem>
<Collapse in={open} timeout={100} unmountOnExit>
<List component="div" disablePadding>
{page.submenu.map((sub, index) => {
return (
<React.Fragment key={sub.title}>
<ListItem
className={classes.nested}
disableGutters
key={sub.title}
>
<Button
activeClassName={classes.active}
className={classes.button}
component={CustomRouterLink}
to={sub.href}
>
<div className={classes.icon}>{sub.icon}</div>
{sub.title}
</Button>
</ListItem>
</React.Fragment>
);
})}
</List>
</Collapse>
</React.Fragment>
))}
</List>
Related
I am trying to build a hamburger menu using Material UI List on Next.js similar to Nested List example on Material UI docs. However, I am keep getting error if I use "collapse" on my code. If I remove collapse then the other parts of the code works fine.
Can anyone tell me what am I doing wrong?
screenshot of an error message
I am trying to build similar to this
import * as React from "react";
import { useState } from "react";
import IconButton from "#mui/material/IconButton";
import ListSubheader from "#mui/material/ListSubheader";
import { Drawer } from "#mui/material";
import List from "#mui/material/List";
import ListItem from "#mui/material/ListItem";
import ListItemButton from "#mui/material/ListItemButton";
import ListItemIcon from "#mui/material/ListItemIcon";
import ListItemText from "#mui/material/ListItemText";
import MenuIcon from "#mui/icons-material/Menu";
import { ExpandLess, ExpandMore } from "#mui/icons-material";
import Collapse from "#mui/material";
const myMenu = [
{
title: "about",
},
{
title: "services",
submenu: [{ title: "Digital Marketing" }, { title: "Promotion" }],
},
{
title: "blog",
},
{
title: "contact",
},
];
const ResponsiveAppBar = () => {
const [openDrawer, setOpenDrawer] = useState(false);
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<React.Fragment>
<Drawer
anchor="right"
open={openDrawer}
onClose={() => setOpenDrawer(false)}
>
<List
sx={{ width: "100%", maxWidth: 360, bgcolor: "background.paper" }}
component="nav"
aria-labelledby="nested-list-subheader"
subheader={
<ListSubheader component="div" id="nested-list-subheader">
Navigation
</ListSubheader>
}
>
{myMenu.map((page, index) =>
page.submenu ? (
<div>
<ListItemButton key={index} onClick={handleClick}>
<ListItemText>{page.title}</ListItemText>
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
{page.submenu.map((sub, index) => {
return (
<ListItemButton key={index}>
<ListItem key={index}>
<ListItemText>{sub.title}</ListItemText>
</ListItem>
</ListItemButton>
);
})}
</List>
</Collapse>
</div>
) : (
<ListItemButton key={index}>
<ListItemIcon>
<ListItemText>{page.title}</ListItemText>
</ListItemIcon>
</ListItemButton>
)
)}
</List>
</Drawer>
<IconButton
sx={{ color: "black", marginLeft: "auto" }}
onClick={() => setOpenDrawer(!openDrawer)}
>
<MenuIcon color="white" />
</IconButton>
</React.Fragment>
);
};
export default ResponsiveAppBar;
The culprit is an incorrect import of Collapse:
import Collapse from "#mui/material";
Since Collapse is a named import, you must import it in one of these two ways:
import { Collapse } from "#mui/material";
// Alternatively
import Collapse from "#mui/material/Collapse";
I'm writing custom nested recursive accordion component to display objects, In that component I'm getting an error each child in a list should have a unique key prop, not sure where I need to put the key property
how to resolve the same.
accordion.js:
import React, { useState, useCallback } from 'react'
import { Container, Grid } from '#material-ui/core'
import './styles.css'
function Accodian({ explorer }) {
const [ expand, setExpand ] = useState(false)
const handleExpand = useCallback(() => {
setExpand(prevState => !prevState)
})
if (explorer.children) {
return (
<div style={{ width: '100%' }} className={'tabs'} key={explorer.label}>
{explorer.children ? (
<>
<div className='tab' onClick={handleExpand}>
<label className={ expand ? 'tab-label-expanded' : 'tab-label' }>
{explorer.label}
</label>
</div>
{expand ? (
<Container className='tab-content'>
<Grid container spacing={1}>
{explorer.children.map(child => {
return (
<React.Fragment>
{Array.isArray(child.children) ? (
<Accodian explorer={child}/>
) : (
<Grid item xs={12} sm={6} md={6} lg={4} xl={3}>
<li>
<b>{child.label}</b>{' '}: {child.value}
</li>
</Grid>
)}
</React.Fragment>
)
})}
</Grid>
</Container>
) : null}
</>
) : null}
</div>
)
} else {
return <div style={{ paddingLeft: '20px' }}>{explorer.label}</div>
}
}
export default Accodian
After did many analysis found the place where we can able to apply the key in the component
Solution: <React.Fragment key={child.label}>
import React, { useState, useCallback } from 'react'
import { Container, Grid } from '#material-ui/core'
import './styles.css'
function Accodian({ explorer }) {
const [ expand, setExpand ] = useState(false)
const handleExpand = useCallback(() => {
setExpand(prevState => !prevState)
})
if (explorer.children) {
return (
<div style={{ width: '100%' }} className={'tabs'} key={explorer.label}>
{explorer.children ? (
<>
<div className='tab' onClick={handleExpand}>
<label className={ expand ? 'tab-label-expanded' : 'tab-label' }>
{explorer.label}
</label>
</div>
{expand ? (
<Container className='tab-content'>
<Grid container spacing={1}>
{explorer.children.map(child => {
return (
<React.Fragment key={child.label}> // applied key
{Array.isArray(child.children) ? (
<Accodian explorer={child}/>
) : (
<Grid item xs={12} sm={6} md={6} lg={4} xl={3}>
<li>
<b>{child.label}</b>{' '}: {child.value}
</li>
</Grid>
)}
</React.Fragment>
)
})}
</Grid>
</Container>
) : null}
</>
) : null}
</div>
)
} else {
return <div style={{ paddingLeft: '20px' }}>{explorer.label}</div>
}
}
export default Accodian
I am getting this error on my React material UI project
By looking at the error I guess it comes somewhere inside the Drawer.js component.
This is my full Drawer.js component
import React, { Fragment, useState } from "react";
import clsx from "clsx";
import { makeStyles, useTheme } from "#material-ui/core/styles";
import Drawer from "#material-ui/core/Drawer";
import { List, Collapse } from "#material-ui/core";
import Divider from "#material-ui/core/Divider";
import ListItem from "#material-ui/core/ListItem";
import IconButton from "#material-ui/core/IconButton";
import ListItemText from "#material-ui/core/ListItemText";
import { toggleDrawer } from "../../store/actions/authActions";
import ExpandLess from "#material-ui/icons/ExpandLess";
import ExpandMore from "#material-ui/icons/ExpandMore";
import ChevronLeftIcon from "#material-ui/icons/ChevronLeft";
import ChevronRightIcon from "#material-ui/icons/ChevronRight";
// import ClickAwayListener from '#material-ui/core/ClickAwayListener'
import { useHistory } from 'react-router-dom';
import { connect } from "react-redux";
import { withRouter } from "react-router";
const useStyles = makeStyles({
list: {
width: 250,
},
fullList: {
width: "auto",
},
});
function TemporaryDrawer(props) {
const classes = useStyles();
const theme = useTheme();
// const [open, setOpen] = React.useState(false);
const [openIndex, setOpenIndex] = useState(0);
let history = useHistory();
// const handleDrawerOpen = () => {
// setOpen(true);
// };
const handleDrawerClose = () => {
props.toggleDrawer();
};
const handleClick = (index) => {
if (openIndex === index) {
setOpenIndex(-1);
} else {
setOpenIndex(index);
}
};
const onToggle = () => (event) => {
if (
event.type === "keydown" &&
(event.key === "Tab" || event.key === "Shift")
) {
return;
}
props.toggleDrawer();
};
const onRoute = (path) => {
// props.history.push(path);
history.push(path);
props.toggleDrawer();
};
const list = (anchor) => (
<div
className={clsx(classes.list, {
[classes.fullList]: anchor === "top" || anchor === "bottom",
})}
role="presentation"
>
<div className={classes.drawerHeader}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === "ltr" ? (
<ChevronLeftIcon />
) : (
<ChevronRightIcon />
)}
</IconButton>
</div>
<Divider />
<List>
{props.permissions.map((route, index) => (
<Fragment key={index}>
<ListItem button onClick={(e) => handleClick(index)}>
<ListItemText primary={route.name} />
{index === openIndex ? <ExpandLess /> : <ExpandMore />}
</ListItem>
{route.children.length && (
<Collapse
in={openIndex === index ? true : false}
timeout="auto"
unmountOnExit
>
<List component="div" disablePadding>
{route.children.map((child, idx) => (
<ListItem
button
className={classes.nested}
key={idx}
onClick={() => onRoute(child.path)}
>
<ListItemText primary={child.name} />
</ListItem>
))}
</List>
<Divider />
</Collapse>
)}
</Fragment>
))}
</List>
{/* <Divider /> */}
</div>
);
return (
<div>
{props.token && (
<Drawer
anchor="left"
open={props.isDrawerOpen}
onClose={onToggle("left", false)}
variant="persistent"
>
{list("left")}
</Drawer>
)}
</div>
);
}
const mapStateToProps = (state) => {
return {
isDrawerOpen: state.auth.isDrawerOpen,
token: state.auth.token,
permissions: state.auth.routes,
};
};
export default withRouter(
connect(mapStateToProps, { toggleDrawer })(TemporaryDrawer)
);
I go through this error and some say this is a problem in MUI library and no way to fix this. But I believe there must be a workaround for this. This causes serious problems for UI.
Where this error comes from and what can I do to fix this?
Any help!
Thanks in advance. =)
I use material UI 4.11.0
and react 16
You only need to create a new childComponent with react.forwardRef passing respective props and refs:
const ChildComponent = React.forwardRef((props, ref) =>
<div ref={ref}>
<yourChildcomponent {...props} />
</div>
);
In your render change the name of the original Child for the new:
<ChildComponent... />
so i am trying to create a list, whereby a list is displaying many items, and two of the items are expandable, and expanding them shows more items(subitems). I have managed to display the list, and the sub-lists, however, clicking either one of the expandable items, expands both items and not just the single one i clicked.
So firstly, i have seperated the listItems as a data structure where i can retrieve them. This is the list Items:
// Skills list in the About Page
export const listItems = [
{
listText: 'Html',
listIcon: <SendIcon/>
},
{
listText: 'CSS',
listIcon: <DraftsIcon />
},
{
listText: 'JavaScript',
listIcon: <InboxIcon />
},
{
listText: 'React',
listIcon: <SendIcon/>,
expan: true,
// SubItems
firstText:'React-Router',
secondText:'React-Navigation',
thirdText:'React-Native',
},
{
listText: 'Database',
listIcon: <DraftsIcon />,
expan: true,
// SubItems
firstText:'FireBase',
secondText:'SQL',
},
{
listText: 'ReactJs',
listIcon: <DraftsIcon />
},
{
listText: 'ReactJs',
listIcon: <DraftsIcon />
}]
This is the code where i am trying to implement the list:
import React, { Fragment } from 'react'
import Styles from './Styles'
// ListItems
import List from '#material-ui/core/List';
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import ExpandLess from '#material-ui/icons/ExpandLess';
import ExpandMore from '#material-ui/icons/ExpandMore';
import StarBorder from '#material-ui/icons/StarBorder';
import Collapse from '#material-ui/core/Collapse';
import {listItems} from './ListItems'
const AboutSkills = () => {
const classes = Styles()
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
const outputList = () => (
<>
<List
style={{color:'white'}}
component="nav"
className={classes.root}
>
{ //Map through the ListItems and...
listItems.map((item, index) => {
// if expandable items exist, expand them
if(item.expan)
{
{/* Use fragment instad of <></> because key attribute is required */}
return <Fragment key={index}>
<ListItem button onClick={handleClick} className={classes.aboutList}>
<ListItemIcon className={classes.aboutIcon}>
{item.listIcon}
</ListItemIcon>
<ListItemText primary={item.listText} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemText classes={{primary:classes.expanText}}
primary={item.firstText} />
</ListItem>
{/* {console.log(item.secondText)} */}
{ item.secondText //if seconditem exists...
? <ListItem button className={classes.nested}>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemText classes=
{{primary:classes.expanText}} primary={item.secondText} />
</ListItem>
: console.log('No Third Item')}
{ item.thirdText //if seconditem exists...
? <ListItem button className={classes.nested}>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemText classes=
{{primary:classes.expanText}} primary={item.thirdText} />
</ListItem>
: console.log('No Third Item')}
</List>
</Collapse>
</Fragment>
} else {
return <ListItem button className={classes.aboutList} key={index}>
<ListItemIcon className={classes.aboutIcon}>
{item.listIcon}
</ListItemIcon>
<ListItemText classes={{primary:classes.unExpanText}} primary=
{item.listText} />
</ListItem>
}
})}
</List>
</>
)
return (
outputList()
)
}
export default AboutSkills
My answer in this thread is pretty much what you are searching for.
Just adapt the code according to your situation.
I am trying to convert the setState into useState.
so I followed the below article and converted partially
https://medium.com/javascript-in-plain-english/state-management-with-react-hooks-no-redux-or-context-api-8b3035ceecf8- but not sure how to convert the props
but its not rendering the values.
so I debugged and put console inside useEffect.
I am getting undefind at this line, am I using useState wrongly
useEffect(() => {
console.log("useEffect setspHeight--->", setspHeight);
can you let me know how to fix it and do I need to make any other changes for react hooks
class component code
import React, { Fragment, useState, Component } from 'react';
import styles from './styles';
import { withStyles } from '#material-ui/core/styles';
import classnames from 'classnames';
import ExpandMoreIcon from '#material-ui/icons/ExpandMore';
import IconButton from '#material-ui/core/IconButton';
import Button from '#material-ui/core/Button';
import ExpansionPanel from '#material-ui/core/ExpansionPanel';
import ExpansionPanelSummary from '#material-ui/core/ExpansionPanelSummary';
import ExpansionPanelDetails from '#material-ui/core/ExpansionPanelDetails';
import Typography from '#material-ui/core/Typography';
import Drawer from '#material-ui/core/Drawer';
import AppBar from '#material-ui/core/AppBar';
import Tabs from '#material-ui/core/Tabs';
import Tab from '#material-ui/core/Tab';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import FormControl from '#material-ui/core/FormControl';
import FormLabel from '#material-ui/core/FormLabel';
import Checkbox from '#material-ui/core/Checkbox';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import dataStyles from '../../../../styles.css';
function TabContainer(props) {
return (
<Typography component="div" style={{ padding: 8 * 3 }}>
{props.children}
</Typography>
);
}
const radioValues = [
{
label: 'Select All Providers for This Category',
value: 'PRO',
},
];
class SportsExpansion extends Component {
state = {
value: 0,
spHeight: [],
spLength: '',
};
componentDidMount() {
this.setState({ spHeight: this.props.spHeight });
if (
this.props.spHeight.filter(
check => check.spWeight === 'One'
).length > 0
) {
this.setState({ value: 0 });
} else if (
this.props.spHeight.filter(
check => check.spWeight === 'Two'
).length > 0
) {
this.setState({ value: 1 });
}
}
handleChange = (event, value) => {
console.log('handleChange -value', value);
this.setState({ value });
};
handleSportsRadioValueChange = (category, value) => {
console.log('handleSportsRadioValueChange -category', category);
console.log('handleSportsRadioValueChange -value', value);
this.setState({ spLength: value });
};
render() {
const { classes, data } = this.props;
let udVal = '';
let starVal = '';
udVal = data.udVals ? data.udVals[0].number : '';
starVal = data.starVals ? data.starVals[0].number : '';
const { canEdit, value } = this.state;
const { spHeight } = this.state;
return (
<div>
<AppBar
className={classes.benchmarkTabHeader}
position="static"
color="default"
>
<Tabs
onChange={this.handleChange}
variant="scrollable"
scrollButtons="on"
indicatorColor="primary"
textColor="primary"
style={{ display: 'block' }}
classes={{
indicator: classes.tabsIndicator,
scrollButtons: classes.MuiPrivateTabScrollButton,
}}
>
<Tab
style={{
display:
this.state.spHeight.filter(
check =>
check.spWeight === 'One'
).length === 0
? 'none'
: '',
color: value == 0 ? '#1976D2' : '#66696C',
}}
label={`Groups (${
this.state.spHeight.filter(
check =>
check.spWeight === 'One'
).length
})`}
icon={
<FontAwesomeIcon style={{ display: 'block' }} />
}
classes={{
root: classes.tabRoot,
selected: classes.tabSelected,
wrapper: classes.alignment,
}}
/>
<Tab
style={{
display:
this.state.spHeight.filter(
check =>
check.spWeight ===
'Two'
).length === 0
? 'none'
: '',
color: value == 1 ? '#1976D2' : '#66696C',
}}
label={`Two (${
this.state.spHeight.filter(
check =>
check.spWeight ===
'Two'
).length
})`}
icon={
<FontAwesomeIcon style={{ display: 'block' }} />
}
classes={{
root: classes.tabRoot,
selected: classes.tabSelected,
wrapper: classes.alignment,
}}
/>
</Tabs>
</AppBar>
{value === 0 && (
<TabContainer>
<div>
{' '}
<FormControl
component="fieldset"
className={classes.formControl}
>
<FormLabel component="legend" />
<RadioGroup
aria-label="Gender"
name="gender1"
className={classes.one}
value={this.state.spLength}
onChange={e => {
this.setState({
spLength: e.target.value,
});
}}
>
{this.state.spHeight
.filter(
check =>
check.spWeight ===
'One'
)
.map((radio, radioIndex) => {
return (
<FormControlLabel
key={radioIndex}
value={radio.value}
control={<Radio />}
label={radio.label}
classes={{
label:
classes.checkboxLabel,
}}
/>
);
})}
)}
</RadioGroup>
</FormControl>
<div className="tiger-button-container">
<Button
variant="outlined"
color="primary"
size="small"
className="tiger-button-upload"
>
ghsd jkjkjk
</Button>
</div>
<Drawer
style={{ width: 500 }}
anchor="right"
open={this.state.right}
>
<div tabIndex={0} role="button"></div>
</Drawer>
</div>
</TabContainer>
)}
{value === 1 && (
<TabContainer>
<div>
<div>
<FormControl
component="fieldset"
className={classes.formControl}
>
<RadioGroup
aria-label="Gender"
name="gender1"
className={classes.one}
value={this.state.spLength}
onChange={e => {
this.setState({
spLength:
e.target.value,
});
}}
>
{this.state.spHeight
.filter(
check =>
check.spWeight ===
'Two'
)
.map((radio, radioIndex) => {
return (
<FormControlLabel
key={radioIndex}
value={radio.label}
control={<Radio />}
label={radio.label}
classes={{
label:
classes.checkboxLabel,
}}
/>
);
})}
</RadioGroup>
</FormControl>
<div className="tiger-button-container">
<Button
variant="outlined"
color="primary"
size="small"
className="tiger-button-upload"
>
ghsd jkjkjk
</Button>
</div>
</div>
</div>
</TabContainer>
)}
</div>
);
}
}
export default withStyles(styles)(SportsExpansion);
////////////////////////////////////////////////
functional component code
import React, { Fragment, useState, useEffect, Component } from 'react';
import styles from './styles';
import { withStyles } from '#material-ui/core/styles';
import classnames from 'classnames';
import ExpandMoreIcon from '#material-ui/icons/ExpandMore';
import IconButton from '#material-ui/core/IconButton';
import Button from '#material-ui/core/Button';
import ExpansionPanel from '#material-ui/core/ExpansionPanel';
import ExpansionPanelSummary from '#material-ui/core/ExpansionPanelSummary';
import ExpansionPanelDetails from '#material-ui/core/ExpansionPanelDetails';
import Typography from '#material-ui/core/Typography';
import Drawer from '#material-ui/core/Drawer';
import AppBar from '#material-ui/core/AppBar';
import Tabs from '#material-ui/core/Tabs';
import Tab from '#material-ui/core/Tab';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import FormControl from '#material-ui/core/FormControl';
import FormLabel from '#material-ui/core/FormLabel';
import Checkbox from '#material-ui/core/Checkbox';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import dataStyles from '../../../../styles.css';
function TabContainer(props) {
return (
<Typography component="div" style={{ padding: 8 * 3 }}>
{props.children}
</Typography>
);
}
const radioValues = [
{
label: 'Select All Providers for This Category',
value: 'PRO',
},
];
//class SportsExpansion extends Component {
const SportsExpansion = (props) => {
const [value, setValue] = useState(0);
const [spHeight, setspHeight] = useState([]);
const [spLength, setspLength] = useState('');
// const { classes, data } = this.props;
const { classes, data } = props;
let udVal = '';
let starVal = '';
udVal = data.udVals ? data.udVals[0].number : '';
starVal = data.starVals ? data.starVals[0].number : '';
// const { canEdit, value } = this.state;
// const { spHeight } = this.state;
useEffect(() => {
// code to run on component mount
console.log("useEffect setspHeight--->", setspHeight);
//this.setState({ spHeight: this.props.spHeight });
setspHeight(spHeight);
if (
spHeight.filter(
check => check.spWeight === 'One'
).length > 0
) {
useState({ value: 0 });
} else if (
spHeight.filter(
check => check.spWeight === 'Two'
).length > 0
) {
useState({ value: 1 });
}
}, [])
//handleChange = (event, value) => {
const handleChange = (event, value) => {
console.log('handleChange -value', value);
useState({ value });
};
// handleSportsRadioValueChange = (category, value) => {
const handleSportsRadioValueChange = (category, value) => {
console.log('handleSportsRadioValueChange -category', category);
console.log('handleSportsRadioValueChange -value', value);
useState({ spLength: value });
};
return (
<div>
<AppBar
className={classes.benchmarkTabHeader}
position="static"
color="default"
>
<Tabs
onChange={this.handleChange}
variant="scrollable"
scrollButtons="on"
indicatorColor="primary"
textColor="primary"
style={{ display: 'block' }}
classes={{
indicator: classes.tabsIndicator,
scrollButtons: classes.MuiPrivateTabScrollButton,
}}
>
<Tab
style={{
display:
//this.state.spHeight.filter(
spHeight.filter(
check =>
check.spWeight === 'One'
).length === 0
? 'none'
: '',
color: value == 0 ? '#1976D2' : '#66696C',
}}
label={`Groups (${
//this.state.spHeight.filter(
spHeight.filter(
check =>
check.spWeight === 'One'
).length
})`}
icon={
<FontAwesomeIcon style={{ display: 'block' }} />
}
classes={{
root: classes.tabRoot,
selected: classes.tabSelected,
wrapper: classes.alignment,
}}
/>
<Tab
style={{
display:
//this.state.spHeight.filter(
spHeight.filter(
check =>
check.spWeight ===
'Two'
).length === 0
? 'none'
: '',
color: value == 1 ? '#1976D2' : '#66696C',
}}
label={`Two (${
//this.state.spHeight.filter(
spHeight.filter(
check =>
check.spWeight ===
'Two'
).length
})`}
icon={
<FontAwesomeIcon style={{ display: 'block' }} />
}
classes={{
root: classes.tabRoot,
selected: classes.tabSelected,
wrapper: classes.alignment,
}}
/>
</Tabs>
</AppBar>
{value === 0 && (
<TabContainer>
<div>
{' '}
<FormControl
component="fieldset"
className={classes.formControl}
>
<FormLabel component="legend" />
<RadioGroup
aria-label="Gender"
name="gender1"
className={classes.one}
value={//this.state.spLength
spLength}
onChange={e => {
useState({
spLength: e.target.value,
});
}}
>
{//this.state.spHeight
spHeight
.filter(
check =>
check.spWeight ===
'One'
)
.map((radio, radioIndex) => {
return (
<FormControlLabel
key={radioIndex}
value={radio.value}
control={<Radio />}
label={radio.label}
classes={{
label:
classes.checkboxLabel,
}}
/>
);
})}
)}
</RadioGroup>
</FormControl>
<div className="tiger-button-container">
<Button
variant="outlined"
color="primary"
size="small"
className="tiger-button-upload"
>
ghsd jkjkjk
</Button>
</div>
{/*<Drawer
style={{ width: 500 }}
anchor="right"
open={
//this.state.right
right}
>
<div tabIndex={0} role="button"></div>
</Drawer>*/}
</div>
</TabContainer>
)}
{value === 1 && (
<TabContainer>
<div>
<div>
<FormControl
component="fieldset"
className={classes.formControl}
>
<RadioGroup
aria-label="Gender"
name="gender1"
className={classes.one}
value={//this.state.spLength
spLength}
onChange={e => {
useState({
spLength:
e.target.value,
});
}}
>
{//this.state.spHeight
spHeight
.filter(
check =>
check.spWeight ===
'Two'
)
.map((radio, radioIndex) => {
return (
<FormControlLabel
key={radioIndex}
value={radio.label}
control={<Radio />}
label={radio.label}
classes={{
label:
classes.checkboxLabel,
}}
/>
);
})}
</RadioGroup>
</FormControl>
<div className="tiger-button-container">
<Button
variant="outlined"
color="primary"
size="small"
className="tiger-button-upload"
>
ghsd jkjkjk
</Button>
</div>
</div>
</div>
</TabContainer>
)}
</div>
);
}
export default withStyles(styles)(SportsExpansion);
You have to replace where you call useState({ value: 1 }); to setValue(value)
You are using useState wrong. useState replaces the state object. The first value in the array is the value you can call in your component. The second value in the array replaces this.setState and sets the value of the state instance. So to use the useState hook if you had the following:
const [value, setValue] = useState(0);
you would use value in your component to reference this state instance. And you would use setValue to set the value of this state instance. So to set value to 2 you would do setValue(2).