Reputation: 423
I have a component ProfileDetails
that has a toggle function to toggle additional information on a profile. I'm importing ProfileDetails
to a component ProfileTable
and trying to pass isOpen
with ProfileDetails
. To then do a ternary operator with the condition isOpen. I am getting isOpen is undefined when doing so
ProfileDetails :
function ProfileDetails() {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => {
setIsOpen(!isOpen);
};
return (
<>
<Button>
<ArrowForwardIosIcon
size="small"
onClick={toggle}></ArrowForwardIosIcon>{" "}
</Button>
<Slider open={isOpen} />
</>
);
}
ProfileTable:
import React, { useState, Fragment } from "react";
import format from "date-fns/format";
import Button from "@material-ui/core/Button";
import { withStyles } from "@material-ui/core/styles";
import DataTable from "../DataTable";
import ArrowForwardIosIcon from "@material-ui/icons/ArrowForwardIos";
import ProfileDetails from "./ProfileDetails ";
function ProfileTable(props, isOpen) {
const { classes } = props;
const drawerColumns = [
{
name: "Name",
label: "Name",
options: {
filter: true,
sort: false,
customBodyRender: (value, tableMeta) => {
return (
<Button size="small" onClick={() => {}}>
{value}
</Button>
);
}
}
},
{
name: "Address",
label: "Address",
options: {
filter: false,
sort: true
}
},
{
name: "Zip",
label: "Zip",
options: {
filter: false,
sort: true
}
},
{
name: "",
label: "",
options: {
filter: false,
sort: false,
customBodyRender: (value, tableMeta) => {
return <ProfileDetails isOpen={isOpen} />;
}
}
}
];
const options = {
search: false,
print: false,
download: false,
selectableRows: "multiple",
expandableRows: false
};
return isOpen ? (
<DataTable
title="Shifts to be Approved"
data={details}
columns={drawerColumns}
options={options}
/>
) : (
<DataTable
title="Shifts to be Approved"
data={details}
columns={columns}
options={options}
/>
);
}
export default withStyles(styles)(ProfileTable);
Upvotes: 1
Views: 7055
Reputation: 777
Thanks for updating your question. user8544110's answer is correct in terms of moving the state into the child component, else if you had more than one ProfileTable toggling one would toggle all.
ProfileTable has isOpen as undefined as functional components only have one parameter passed down for props which is an object of all the props passed to it. Therefore you can pick up the isOpen as follows:
function ProfileTable(props) {
const { classes, isOpen } = props;
...
}
Or using arrow functions you can:
const ProfileTable = ({ classes, isOpen }) => {
...
}
Upvotes: 5
Reputation: 2922
isOpen
is undefined
because your ProfileDetails
component is not getting any prop in the definition of the functional component. If you want to use the component like that, you should do the following:
function ProfileDetails(isOpenProp) {
const [isOpen, setIsOpen] = useState(isOpenProp);
const toggle = () => {
setIsOpen(!isOpen);
};
return (
<>
<Button>
<ArrowForwardIosIcon
size="small"
onClick={toggle}></ArrowForwardIosIcon>{" "}
</Button>
<Slider open={isOpen} />
</>
);
}
That way, the initial value for isOpen
would be the prop that you are passing from ProfileTable
. Hope this helps.
Upvotes: 2
Reputation: 11
Use isOpen as a state of a component that is the parent of both ProfileDetails and ProfileTable and implement toggle function in that component too. Pass reference of the toggle function to ProfileDetails. Also, pass isOpen to ProfileTable. Now you can toggle the value of isOpen from ProfileDetails component and use that value in ProfileTable component.
Upvotes: 0