Topic: MDBDateTimePicker infinite loop when trying to use onChange callback
jammerxd2 priority asked 1 year ago
Expected behavior
I can use an onChange callback designated as
const onStartDateTimeChanged = (e:any)=>{
if(StringIsNullOrEmpty(e)) return;
setStartDateTime(e);
};
Actual behavior
As soon as a datetime is selected an infinite loop begins that just keeps recalling the onchange callback with the same value.
It appears it has been over a year from another support thread and this issue still hasn't been resolved. Very disappointing.
Resources (screenshots, code snippets etc.)
My component looks like this:
<MDBModal tabIndex='-1' show={showModal} setShow={setShowModal} nonInvasive>
<MDBModalDialog centered scrollable>
<MDBModalContent>
<MDBModalHeader>
<MDBModalTitle>{modalTitle}</MDBModalTitle>
<MDBBtn className='btn-close' color='none' onClick={toggleShow}></MDBBtn>
</MDBModalHeader>
<MDBModalBody>
<MDBInputGroup className='mb-4'>
<MDBDateTimepicker inline inputToggle label="Start DateTime"
dateFormat={'mm-dd-yyyy'}
onChange={(e)=>{onStartDateTimeChanged(e)}} required/>
</MDBInputGroup>
</MDBModalBody>
<MDBModalFooter>
<MDBBtn color='secondary' onClick={()=>{toggleShow();if(onModalClose !== null && onModalClose !== undefined) { onModalClose()}}}>
Close
</MDBBtn>
<MDBBtn type="button" onClick={()=>{onBtnConfirmClick()}}>Confirm</MDBBtn>
</MDBModalFooter>
</MDBModalContent>
</MDBModalDialog>
</MDBModal>
And is hosted inside an MDBModal component.
Mateusz Lazaru staff answered 1 year ago
I was able to reproduce was triggering the onChange
event when any state of the wrapper changes. That's obviously a bug, and we're going to fix it soon. We are currently working to generally improve pickers.
Could you tell me if you get an endless loop issue with this code? I didn't find it.
import React, { useCallback, useState } from 'react';
import {
MDBContainer,
MDBCol,
MDBDateTimepicker,
MDBModal,
MDBModalBody,
MDBModalDialog,
MDBModalContent,
MDBModalHeader,
MDBModalTitle,
MDBBtn,
MDBModalFooter,
MDBInputGroup,
} from 'mdb-react-ui-kit';
export default function DateTimepickerPage() {
const [startDateTime, setStartDateTime] = useState(new Date());
const [showModal, setShowModal] = useState(false);
const [onModalClose, setOnModalClose] = useState(null);
const toggleShow = () => setShowModal(!showModal);
const onBtnConfirmClick = () => {
toggleShow();
};
const onStartDateTimeChanged = (e: any) => {
console.log('onStartDateTimeChanged');
setStartDateTime(e);
};
return (
<MDBContainer>
<button className='btn btn-primary' onClick={() => setShowModal(true)}>
click
</button>
<MDBModal tabIndex='-1' show={showModal} setShow={setShowModal} nonInvasive>
<MDBModalDialog centered scrollable>
<MDBModalContent>
<MDBModalHeader>
<MDBModalTitle>Title</MDBModalTitle>
<MDBBtn className='btn-close' color='none' onClick={toggleShow}></MDBBtn>
</MDBModalHeader>
<MDBModalBody>
<MDBInputGroup className='mb-4'>
<MDBDateTimepicker
inline
inputToggle
label='Start DateTime'
dateFormat={'mm-dd-yyyy'}
onChange={(e) => {
onStartDateTimeChanged(e);
}}
required
/>
</MDBInputGroup>
</MDBModalBody>
<MDBModalFooter>
<MDBBtn
color='secondary'
onClick={() => {
toggleShow();
if (onModalClose !== null && onModalClose !== undefined) {
onModalClose();
}
}}
>
Close
</MDBBtn>
<MDBBtn
type='button'
onClick={() => {
onBtnConfirmClick();
}}
>
Confirm
</MDBBtn>
</MDBModalFooter>
</MDBModalContent>
</MDBModalDialog>
</MDBModal>
</MDBContainer>
);
}
jammerxd2 priority commented 1 year ago
unfortunately I'm already out of time for this particular issue on the project I'm working on and need to wait for a fix before I try this component out again.
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- ForumUser: Priority
- Premium support: Yes
- Technology: MDB React
- MDB Version: MDB5 6.3.0
- Device: PC
- Browser: Firefox, Chrome, Edge
- OS: Windows 11
- Provided sample code: No
- Provided link: No
jammerxd2 priority commented 1 year ago
Additionally, I am using useCallback to memorize certain functions to maintain state. It seems that whenever ANY of the state values on the component change, the 'onChange' method is called despite the value not changing.
jammerxd2 priority commented 1 year ago
It also appears that using an onChange method that is wrapped in useCallback triggers an infinite onChange callback loop once a value is selected. Screenshot: https://gyazo.com/7807e7ddf893604ea0159a9ed6ac90c3
The infinite loop also starts if I modify a state variable on the component containing the MDBDateTimePicker - it triggers a re-render then immediately infinitely calls the onChange callback.