Home > Software engineering >  Not able to setValue in useState in React Material-UI
Not able to setValue in useState in React Material-UI

Time:10-14

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>
  • Related