I have a component with the following
const [isOpen, setIsOpen] = useState(false);
{isOpen && (
<Drop
overflow="unset"
align={{ right: "left", top: "bottom", bottom: "bottom" }}
style={{ overflowY: "scroll" }}
target={targetRef.current}
onClickOutside={() => setIsOpen(false)}
onEsc={() => setIsOpen(false)}
>
<Calendar
date={
value
? moment(value)
.format()
.split("T")[0]
: null
}
onSelect={evt => {
onCalendarSelect(evt.toString());
}}
size="small"
{...(calendarPassedProps as CalendarProps)}
/>
</Drop>
)}
useEffect(() => {
console.log("useEffect ",isOpen)
}, [isOpen])
Where onCalendarSelect is
const onCalendarSelect = (v: string) => {
console.log(isOpen) //always showing true
setIsOpen(false)
const date = moment(v)
.format()
.split("T")[0]
.replaceAll("-", "/");
try {
setValue(date);
if (onChange) {
onChange(date);
}
} catch (e) {
// Prevent invalid dates
}
};
Now, when I click outside of the drop , and onCLickOutside is triggered, my isOpen useEffect is triggered, hence closing the calendar.
But whenever I trigger the function OnCalendarSelect which does setIsOpen(false)
, nothing changes and the useeffect is not being triggered.
What can the issue be?
CodePudding user response:
1.You are not providing a complete component example so we know if there are conflicts, if there's a different setIsOpen that overwrites the one in this component or any other bugs that might be caused by your logic. 2.You are not specifying the relationship of onCalendarSelect and this component. Are you passing the function as a prop? Are you extracting it from context? Is it defined inside the component? 3. Do you have another setIsOpen in the app that could overwrite the one here?
However. I think you should pass the setIsOpen function to your onCalendarSelect function. As in the example below. If this does not work please provide the full component code and the code of the component where onCalendarSelect is.
const [isOpen, setIsOpen] = useState(false);
{isOpen && (
<Drop
overflow="unset"
align={{ right: "left", top: "bottom", bottom: "bottom" }}
style={{ overflowY: "scroll" }}
target={targetRef.current}
onClickOutside={() => setIsOpen(false)}
onEsc={() => setIsOpen(false)}
>
<Calendar
date={
value
? moment(value)
.format()
.split("T")[0]
: null
}
onSelect={evt => {
onCalendarSelect(evt.toString(), setIsOpen);
}}
size="small"
{...(calendarPassedProps as CalendarProps)}
/>
</Drop>
)}
useEffect(() => {
console.log("useEffect ",isOpen)
}, [isOpen])
const onCalendarSelect = (v: string, setIsOpen: any) => {
console.log(isOpen) //always showing true
setIsOpen(false)
const date = moment(v)
.format()
.split("T")[0]
.replaceAll("-", "/");
try {
setValue(date);
if (onChange) {
onChange(date);
}
} catch (e) {
// Prevent invalid dates
}
};
CodePudding user response:
Fixed by adding a evt.stopPropagation
<Drop
overflow="unset"
align={{ right: "left", top: "bottom", bottom: "bottom" }}
style={{ overflowY: "scroll" }}
target={targetRef.current}
onClickOutside={() => setIsOpen(false)}
onClick={(evt: React.MouseEvent) => {
evt.stopPropagation();
}}
>
CodePudding user response:
Invalid return and render.
Try it
const [isOpen, setIsOpen] = useState(false);
useEffect(() => {
console.log("useEffect ", isOpen);
}, [isOpen]);
return(
<>
<Drop
overflow="unset"
align={{ right: "left", top: "bottom", bottom: "bottom" }}
style={{ overflowY: "scroll" }}
target={targetRef.current}
onClickOutside={() => setIsOpen(false)}
onEsc={() => setIsOpen(false)}
>
<Calendar
date={
value
? moment(value)
.format()
.split("T")[0]
: null
}
onSelect={evt => {
onCalendarSelect(evt.toString());
}}
size="small"
{...(calendarPassedProps as CalendarProps)}
/>
</Drop>
</>
)