0

Im using Material UI Checkbox to create a form that takes input and then in theory adds the new values or updates the values into a state object. This form is used for both editing a holiday or creating a new holiday.

I'm struggling with finding why my state isnt being updated upon clicking on a checkbox or typing in an input box. The checkbox wont change to checked/unchecked and the input wont remvoe the value when i use backspace to remove characters or enter new characters.

Dialog Box: DialogBox

HolidayData:

{
  "id": 1,
  "ID": 1,
  "HolidayName": "New Year's Day",
  "HolidayDate": "05/20/2020",
  "Branch": null,
  "Hours": null,
  "Web": true,
  "Phone": true,
  "CoOp": false,
  "Active": true,
  "Submitted": null,
  "SubmittedBy": null,
  "Published": "05/20/2020",
  "PublishedBy": "John.Doe"
}

DialogBox Code:

const HolidayDialog = (props) => {

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


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

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

    const handleClose = () => {
        setNoticeModal(false);
    };



    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 ? holidayData.HolidayName : ''}/>
                        </div>
                        <div className="col">
                            <TextField id="outlined-basic" label="Branch" variant="outlined" onChange={updateValues} value={holidayData.Branch ? 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" label="Hours" variant="outlined" onChange={updateValues} value={holidayData.Hours ? holidayData.Hours : 'Closed'}/>
                        </div>
                    </div>
                    <div className="row mt-3">
                        <div className="col d-flex flex-column">
                            <FormControlLabel
                                control={
                                <Checkbox
                                    checked={holidayData.Web ? holidayData.Web : false}
                                    onChange={handleChange}
                                    name="Web"
                                    color="primary"
                                />
                                }
                                label="Show on Web?"
                            />
                            <FormControlLabel
                                control={
                                <Checkbox
                                    checked={holidayData.CoOp ? holidayData.CoOp : false}
                                    onChange={handleChange}
                                    name="CoOp"
                                    color="primary"
                                />
                                }
                                label="CoOp Holiday?"
                            />
                        </div>
                        <div className="col d-flex flex-column">
                            <FormControlLabel
                                control={
                                <Checkbox
                                    checked={holidayData.Phone ? holidayData.Phone : false}
                                    onChange={handleChange}
                                    name="Phone"
                                    color="primary"
                                />
                                }
                                label="Use in IVR?"
                            />
                            <FormControlLabel
                                control={
                                <Checkbox
                                    checked={holidayData.Active ? holidayData.Active : false}
                                    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>
    )
}

When i check a box or try to edit an input the handleChange and updateValues are firing. I believe it may be a syntax issue, but i cant seem to find anything. When console.log'ing event.target.name i get the correct name: Web for example

EDIT: The issue appears to be with the value and checked being equal to {holidayData.Phone ? holidayData.Phone : false} or the sorts. However if i bring the values down to {holidayData.Phone} itll start to throw errors:

A component is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).

It'll now allow me to check a checkbox but only once and throws this error over and over again and im not sure why or how to correct this?

1
  • 1
    Please create a code sandbox that reproduces your problem -- ideally with as simple of an example as possible that still reproduces the problem (e.g. your dialog could contain a single checkbox). Commented May 20, 2020 at 18:30

1 Answer 1

2

Most probably the useEffect is causing the issue. You're resetting the data each time the component gets updated. You don't need that if you're already doing that with useState.

Check my example here with only the textbox: https://codesandbox.io/s/fancy-shape-14r63?file=/src/App.js

If you uncomment the useEffect, it stops working.

Sign up to request clarification or add additional context in comments.

3 Comments

This does correct the issue but how do i set the initial state of the data passed into the DialogBox?
You set it when doing const [holidayData, setHolidayData] = React.useState(props.data);. If you check my example it works similarly.
Thank you a million!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.