You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者呂學霖

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 09:13:14