I am dealing with a bug in a library I'm using that will sometimes create invalid values that my code will need, crashing the page. I would like to only apply that new value (the result of useDateRangePickerState
) if it is valid. If not, I do not want to assign that value to my state. How can I do this?
export const DateRangePicker: FC<AriaDateRangePickerProps<DateValue>> = memo((props) => {
const defaultNowTime = {timeValue}
const [nowTime, setNowTime] = useState(defaultNowTime);
const newstate = useDateRangePickerState({
...props,
defaultValue: {
start: defaultNowTime.set({ second: 0, minute: 0, millisecond: 0, hour: 0 }),
end: defaultNowTime
},
hideTimeZone: true,
shouldCloseOnSelect: false,
});
//once a valid 'newstate' is created, cache it with useMemo here?
//cachedOldState = ...
//only use the valid to assign state if its valid! *******************
const state = (newstate is valid) ? newstate : cachedOldState
...
If the useDateRangePickerState
hook part is something that you control then you will want to stop invalid values there before they bubble up. But if it's part of the buggy library then you can make it work.
You've got the right idea here:
//once a valid 'newstate' is created, cache it with useMemo here?
//cachedOldState = ...
//only use the valid to assign state if its valid! *******************
const state = (newstate is valid) ? newstate : cachedOldState
We need to store the previous valid state somewhere. I would use a useState
for that.
Then we need to check changes from the date picker and see if they are valid. I recommend a useEffect
hook with a dependency on the newstate
. This will run every time that the newstate
changes.
If the newstate
is valid we will call setState
and that way we keep our "previous valid state" value in sync.
const newstate = useDateRangePickerState({ /* ... */ });
const [validDate, setValidDate] = useState(initialValue);
useEffect(() => {
if (isValid(newstate)) {
setValidDate(newstate);
}
}, [newstate]);
As a sidenote, I'm really confused by the code in your question. defaultNowTime
is stored in state so isn't it a mutation of state to call defaultNowTime.set
in the defaultValue
?