Charles L.
Charles L.

Reputation: 1960

React not closing dialog box

Im using materialUI to click a menu item that then opens a dialog box(child component) however after the dialogbox opens it wont seem to close and wont update the data for noticeModal. There are not any errors being thrown and i belive it has to do with using useEffect to setNoticeModal(props.open) for the initial state. Ive tried removing the useEffect() and throwing props.open into the default useDate() for the noticeModal however upon doing that then my dialogbox wont open anymore at all. What am i over looking here?

holidaySettings.js

    ...  
    const [dialogOpen, setDialogOpen] = React.useState(false);  
    const handleDialogOpen = (dataElement) => {
      setDialogData(dataElement);
      setDialogOpen(true);
      setOpen(false);
    }

    ...
    <ClickAwayListener onClickAway={handleClose}>
       <MenuList autoFocusItem={open} id="menu-list-grow" onKeyDown={handleListKeyDown}>
          <MenuItem onClick={handleDialogOpen}>Add Holiday</MenuItem>
        </MenuList>
     </ClickAwayListener>

    ...

    <div className="card-body">
      <div className="row">
         <div className="text-left col-12">
            <Styles>
               <Table columns={columns} data={data} />
               <HolidayDialog open={dialogOpen} onClose={handleDialogClose} data={dialogData}/>
            </Styles>
         </div>
       </div>
     </div>
    ...

holidayDialog.js

const HolidayDialog = (props) => {
    const [noticeModal, setNoticeModal] = useState(false);
    const [selectedDate, setSelectedDate] = useState(new Date());
    const [holidayData, setHolidayData] = useState(props.data);

    useEffect(() => {
        setNoticeModal(props.open)
    });

    const handleDateChange = (date) => {
        setSelectedDate(date);
    };

    const handleClose = () => {
        setNoticeModal(false);
        console.log(noticeModal);
    };

    const handleChange = (e) => {
        const { name, checked } = e.target;
        setHolidayData((prevState) => ({ ...prevState, [name]: checked }));
      };

    const updateValues = (e) => {
        const { name, value } = e.target;
        setHolidayData((prevState) => ({ ...prevState, [name]: value }));
    }
    return (
        <Dialog
            open={noticeModal}
            TransitionComponent={Transition}
            keepMounted
            onClose={handleClose}
            aria-labelledby="notice-modal-slide-title"
            aria-describedby="notice-modal-slide-description"
        >
            <DialogTitle id="customized-dialog-title" onClose={handleClose}>
                {holidayData.HolidayName ? holidayData.HolidayName : 'Create New Holiday'}
            </DialogTitle>
            <DialogContent dividers>
                <form noValidate autoComplete="off">
                    <div className="row">
                        <div className="col">
                            <TextField required name="HolidayName" id="outlined-basic" label="Holiday Name" variant="outlined" onChange={updateValues} value={holidayData.HolidayName || ''}/>
                        </div>
                        <div className="col">
                            <TextField id="outlined-basic" name="Branch" label="Branch" variant="outlined" onChange={updateValues} value={holidayData.Branch || 'ALL'}/>
                        </div>
                    </div>
                    <div className="row mt-3">
                        <div className="col">
                        <MuiPickersUtilsProvider utils={DateFnsUtils}>
                            <KeyboardDatePicker
                                disableToolbar
                                variant="inline"
                                format="MM/dd/yyyy"
                                margin="normal"
                                id="date-picker-inline"
                                label="Date picker inline"
                                value={selectedDate}
                                onChange={handleDateChange}
                                KeyboardButtonProps={{
                                    'aria-label': 'change date',
                                }}
                            />
                        </MuiPickersUtilsProvider>
                        </div>
                        <div className="col">
                            <TextField id="outlined-basic" name="Hours" label="Hours" variant="outlined" onChange={updateValues} value={holidayData.Hours || 'Closed'}/>
                        </div>
                    </div>
                    <div className="row mt-3">
                        <div className="col d-flex flex-column">
                            <FormControlLabel
                                control={
                                <Checkbox
                                    checked={holidayData.Web || false}
                                    value={holidayData.Web}
                                    onChange={handleChange}
                                    name="Web"
                                    color="primary"
                                />
                                }
                                label="Show on Web?"
                            />
                            <FormControlLabel
                                control={
                                <Checkbox
                                    checked={holidayData.CoOp || false}
                                    value={holidayData.CoOp}
                                    onChange={handleChange}
                                    name="CoOp"
                                    color="primary"
                                />
                                }
                                label="CoOp Holiday?"
                            />
                        </div>
                        <div className="col d-flex flex-column">
                            <FormControlLabel
                                control={
                                <Checkbox
                                    checked={holidayData.Phone || false}
                                    value={holidayData.Phone}
                                    onChange={handleChange}
                                    name="Phone"
                                    color="primary"
                                />
                                }
                                label="Use in IVR?"
                            />
                            <FormControlLabel
                                control={
                                <Checkbox
                                    checked={holidayData.Active || true}
                                    value={holidayData.Active}
                                    onChange={handleChange}
                                    disabled 
                                    name="Active"
                                    color="primary"
                                />
                                }
                                label="Active"
                            />
                        </div>
                    </div>
                </form>
            </DialogContent>
            <DialogActions>
                <Button autoFocus onClick={handleClose} color="default">
                    Cancel
                </Button>
                <Button autoFocus onClick={handleClose} color="primary">
                    Create Holiday
                </Button>
            </DialogActions>
        </Dialog>
    )
}

export default HolidayDialog;

Upvotes: 0

Views: 2258

Answers (3)

gdh
gdh

Reputation: 13682

You are not providing any dependency to useEffect so it runs on every re-render. In your useEffect you are toggling the modal and hence the issue.

useEffect(() => {
        setNoticeModal(props.open) 
    });//<---- issue - missing dependency

Solution - pass dependency as props.open. This makes the useEffect to run only when props.open is changed.

useEffect(() => {
        setNoticeModal(props.open) 
    }, [props.open]); //<----- props.open

Upvotes: 1

Dipesh KC
Dipesh KC

Reputation: 2463

Could you try this?

I am assuming props.onClose is making dialogOpen to false on parent(holidaySettings)

 const handleClose = () => {
       props.onClose()
    };

If props.onClose is not making dialogOpen to false on parent(holidaySettings).You can add close attribute which sets dialogOpen to false.

     <HolidayDialog open={dialogOpen} close={()=>setDialogOpen(false);} onClose={handleDialogClose} data={dialogData}/>

      const handleClose = () => {
           props.close()
        };

And passing props.open to Dialog

<Dialog
  open={props.open}
/>

Upvotes: 2

Ishant Solanki
Ishant Solanki

Reputation: 207

Inside the useEffect, you are resetting the noticeModal value to props.open which i believe is true?

I believe what you are trying to do is set the initial value of noticeModal. Try changing to the code below and remove the useEffect

const [noticeModal, setNoticeModal] = useState(props.open);

Upvotes: 0

Related Questions