I have created a custom dialog component in Material-UI
const CustomDialog = (props) => {
const [dialogOpenState, setOpen] = React.useState(props.dilaogOpenProp);
return (
<>
<CssBaseline />
<Dialog
fullWidth
onClose={() => {}}
open={dialogOpenState}
maxWidth="xs"
sx={{
backdropFilter: "blur(5px)",
}}
>
<DialogTitle>Example Dialog</DialogTitle>
<DialogContent>Example Content Here</DialogContent>
<DialogActions>
<Button>ooooh.</Button>
</DialogActions>
</Dialog>
<Box
sx={{
minHeight: "100vh",
background:
"url(https://source.unsplash.com/random) no-repeat center center",
backgroundSize: "cover",
}}
></Box>
</>
);
}
export default CustomDialog;
I am trying this to manage open close from another component using useState
const Minidrawer = props => {
const theme = useTheme();
const { history } = props;
const [open, setOpen] = React.useState(false);
const [dialogOpen,setDialogueOpen] = React.useState(false)
const handleDialogueOpen = () => {
console.log("clicked");
setDialogueOpen(true)
}
return (
<Box sx={{ display: 'flex' }}>
<AppBar position="fixed" open={open}>
<Toolbar>
<Typography variant="h6" noWrap component="div">
COMPANY NAME
</Typography>
<Button onClick={handleDialogueOpen}>Filter</Button>
</Toolbar>
</AppBar>
<CustomDialog dilaogOpenProp={dialogOpen}/>
</Box>
);
}
export default withRouter(Minidrawer);
I am trying to set dialogOpen
which is getting passed in Dialog open prop value to false using useState
,I am getting clicked in console but dilaog not getting invoked, also if I manually set the dialogOpen
in useState
its working but not on click, what's going on here?
CodePudding user response:
The problem is that you're copying props to state within CustomDialog
. That means that changes to dilaogOpenProp
in the parent are ignored by CustomDialog
. (This is generally not best practice, but there are edge cases where it can make sense.) Since you're doing that, CustomDialog
only uses the initial value of that prop, not the updated value when your parent component changes it. Here's a simpler example demonstrating that:
You need to either store the open/closed state in the parent and have the parent control it, or store the open/closed state in CustomDialog
and have CustomDialog
control it. You can't do both.
Often that means having the parent be in control, but passing a function to the child that the child can use to tell the parent about a change. For instance, if you need CustomDialog
to be able to close itself (fairly common with dialogs), you can pass it a function the parent provides that does that.
CodePudding user response:
If you want the state from the child component get updated based on the prop provided from the parent, you can use useEffect
. You're passing the prop to useState
in the child component (React.useState(props.dilaogOpenProp)
) which only works in the first render:
const [dialogOpenState, setOpen] = React.useState(props.dilaogOpenProp);
useEffect(() => {
// update the state every time the prop.dilaogOpenProp dependency changes
setOpen(props.dilaogOpenProp);
}, [props.dilaogOpenProp]);
CodePudding user response:
You must keep the state updated, use useState
:
const CustomDialog = ({ dilaogOpenProp }) => {
const [dialogOpenState, setOpen] = React.useState(dilaogOpenProp);
useEffect(() => {
setOpen(props.dialogOpenState);
}, [dilaogOpenProp])
);
}
You can also get the value directly from props
<Dialog open={props.dilaogOpenProp}>
...
</Dialog>