React函数组件中antd DatePicker.RangePicker显示异常求助
解决Antd RangePicker拆分组件后重渲染导致显示异常的问题
问题原因
你遇到的核心问题是**RenderSearch组件定义在ProductEmissions内部**,每次父组件因useState更新重渲染时,RenderSearch都会被重新创建为全新的组件类型,导致它的实例被销毁重建,RangePicker的内部状态(比如弹窗展开状态、选中进度)丢失,进而无法正常显示。
解决方案
方案1:将组件移到外部并通过props传递依赖
把RenderSearch提取到父组件外部,将需要的状态、回调、Form实例等通过props传入,避免组件被反复重新定义。
import { Form, DatePicker, Text } from 'antd'; import type { FormInstance, RangePickerProps } from 'antd'; import { useState } from 'react'; // 提取到父组件外部 const RenderSearch: React.FC<{ form: FormInstance; onSubmit: () => void; dates: RangePickerProps['value']; value: RangePickerProps['value']; disabledDate: RangePickerProps['disabledDate']; setDates: (val: RangePickerProps['value']) => void; setValue: (val: RangePickerProps['value']) => void; onOpenChange: (open: boolean) => void; }> = ({ form, onSubmit, dates, value, disabledDate, setDates, setValue, onOpenChange }) => ( <Form onFinish={onSubmit} style={{ width: '100%' }} form={form}> <Text className='label'>Date</Text> <Form.Item name='month'> <DatePicker.RangePicker value={dates || value} disabledDate={disabledDate} onCalendarChange={(val) => setDates(val)} onChange={(val) => setValue(val)} onOpenChange={onOpenChange} style={{ width: '100%' }} /> </Form.Item> </Form> ); const ProductEmissions: React.FC = () => { const [dates, setDates] = useState<RangePickerProps['value']>(null); const [value, setValue] = useState<RangePickerProps['value']>(null); const [form] = Form.useForm(); const onSubmit = () => { /* 你的提交逻辑 */ }; const disabledDate = (current: RangePickerProps['disabledDate']) => { /* 你的禁用日期逻辑 */ }; const onOpenChange = (open: boolean) => { /* 你的弹窗状态变化逻辑 */ }; return ( <Layout> <ContentArea> <RenderSearch form={form} onSubmit={onSubmit} dates={dates} value={value} disabledDate={disabledDate} setDates={setDates} setValue={setValue} onOpenChange={onOpenChange} /> </ContentArea> </Layout> ); };
方案2:用React.memo包裹内部组件并稳定props
如果必须将RenderSearch留在父组件内部,用React.memo缓存组件,同时用useCallback稳定回调引用,避免不必要的重渲染。
import { Form, DatePicker, Text } from 'antd'; import type { RangePickerProps } from 'antd'; import { useState, useCallback, memo } from 'react'; const ProductEmissions: React.FC = () => { const [dates, setDates] = useState<RangePickerProps['value']>(null); const [value, setValue] = useState<RangePickerProps['value']>(null); const [form] = Form.useForm(); // 用useCallback稳定回调引用,避免每次重渲染生成新函数 const onSubmit = useCallback(() => { /* 你的提交逻辑 */ }, []); const disabledDate = useCallback((current: RangePickerProps['disabledDate']) => { /* 你的禁用日期逻辑 */ }, []); const onOpenChange = useCallback((open: boolean) => { /* 你的弹窗状态变化逻辑 */ }, []); // 用React.memo包裹,缓存组件实例 const RenderSearch = memo(() => ( <Form onFinish={onSubmit} style={{ width: '100%' }} form={form}> <Text className='label'>Date</Text> <Form.Item name='month'> <DatePicker.RangePicker value={dates || value} disabledDate={disabledDate} onCalendarChange={(val) => setDates(val)} onChange={(val) => setValue(val)} onOpenChange={onOpenChange} style={{ width: '100%' }} /> </Form.Item> </Form> )); return ( <Layout> <ContentArea> <RenderSearch /> </ContentArea> </Layout> ); };
内容的提问来源于stack exchange,提问作者呂學霖
相关产品推荐
相关产品推荐

