如何在日期选择器新状态无效时仅沿用旧状态值?
解决第三方日期范围选择器状态无效的问题
要实现仅在useDateRangePickerState返回有效状态时更新组件状态,无效时沿用旧状态,可以按以下步骤操作:
1. 定义状态有效性验证函数
首先明确"无效值"的判断标准,比如检查选中的日期范围是否存在有效起始和结束时间,根据业务场景编写验证逻辑:
// 根据第三方库的实际返回结构调整验证规则 const isStateValid = (state: ReturnType<typeof useDateRangePickerState>): boolean => { // 示例:验证选中范围的起止时间是否为有效DateValue return !!(state?.selectedRange?.start && state?.selectedRange?.end); };
2. 使用useRef缓存有效状态
用useRef持久化存储最近一次的有效状态,它的值不会随组件重新渲染而重置,适合保存跨渲染的状态:
// 初始化时用首次返回的newstate作为初始有效状态 const validStateRef = useRef(newstate);
3. 每次渲染时校验并更新缓存
组件每次渲染时,先验证新返回的newstate,有效则更新缓存的ref;无效则保留旧缓存值:
// 校验新状态,有效则更新缓存 if (isStateValid(newstate)) { validStateRef.current = newstate; } // 最终使用的状态:有效用新状态,无效用缓存的旧状态 const state = validStateRef.current;
修改后的完整代码示例
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, }); // 状态有效性验证函数 const isStateValid = (state: ReturnType<typeof useDateRangePickerState>): boolean => { return !!(state?.selectedRange?.start && state?.selectedRange?.end); }; // 缓存有效状态的ref const validStateRef = useRef(newstate); // 校验并更新缓存 if (isStateValid(newstate)) { validStateRef.current = newstate; } // 使用最终的有效状态 const state = validStateRef.current; // 后续组件逻辑... ... });
额外优化
如果组件依赖isStateValid函数触发重渲染,可以用useCallback包裹它,避免不必要的性能消耗:
const isStateValid = useCallback((state: ReturnType<typeof useDateRangePickerState>): boolean => { return !!(state?.selectedRange?.start && state?.selectedRange?.end); }, []);
内容的提问来源于stack exchange,提问作者Devstar34
相关产品推荐
相关产品推荐

