Cannot update a component X while rendering a different component DatepickerRange
pedropmedina opened this issue · 4 comments
I followed the docs and updating the state from within onChange in DatePicker is causing the error above.
Here's a snippet of the component:
const BaseDateRange: React.FC<BaseDateRangeProps> = ({ onChangeDateRange }) => {
const [startValue, setStartValue] = useState(new Date());
const [endValue, setEndValue] = useState(new Date());
const [showCalendar, setShowCalendar] = useState(false);
const isInvalid = () => compareAsc(startValue, endValue) === 1;
const handleShowCalendar = (show: boolean) => {
if (!show) setShowCalendar(true);
};
return (
<OutsideEvent handler={() => setShowCalendar(false)}>
<DatepickerRange
isCompact={isCompact}
startValue={startValue}
endValue={endValue}
onChange={(changes) => {
if (onChangeDateRange) onChangeDateRange(changes);
if (changes.startValue) setStartValue(changes.startValue);
if (changes.endValue) setEndValue(changes.endValue);
}}
>
<div className="py-2 px-4 relative">
<div className="flex items-center mb-4">
<div className="px-2 text-sm">Date range:</div>
<div>
<Field>
<DatepickerRange.Start>
<StyledInput isCompact={true} onFocus={() => handleShowCalendar(showCalendar)} />
</DatepickerRange.Start>
</Field>
</div>
<div className="px-2 text-sm">to</div>
<div className="max-w-[130px]">
<Field>
<DatepickerRange.End>
<StyledInput
isCompact={true}
validation={isInvalid() ? 'error' : undefined}
onFocus={() => handleShowCalendar(showCalendar)}
/>
</DatepickerRange.End>
{isInvalid() && (
<Message validation="error">End date must occur after the start date</Message>
)}
</Field>
</div>
</div>
{showCalendar && (
<div className="shadow-xl max-w-min px-6 py-4 ml-2 absolute top-[100%] left-0 bg-white">
<DatepickerRange.Calendar />
</div>
)}
</div>
</DatepickerRange>
</OutsideEvent>
);
};
Hi @pedropmedina 👋🏽 . Could you create a minimal CodeSandbox example demonstrating the issue you're encountering, so I can investigate further?
Feel free to use Garden's CodeSandbox template or create a new sandbox example.
Hey @hzhu, sorry for the late response. Here's a link https://codesandbox.io/s/unruffled-feistel-mjj25?file=/src/App.js
Let me know if there's anything else you need - Thanks
Hi @pedropmedina, my investigations indicate that this is a bug on Garden's side relating to state synchronization.
It appears that the onChange
is called immediately with the controlled value — before the DatepickerRage
has had a chance to complete its render. The likely cause of this is that the onChange
is called inside DatepickerRange
's internal reducer where state changes occur. This is problematic because the state changes may not have settled, and reducers must be pure and side effect free. The onChange
function commonly contains side effects from the consumer of the component.
We will continue to investigate the problem and update this issue with progress.
Thanks @pedropmedina! The issue has been fixed in #1309.