diff --git a/src/components/ui/calendar/baseCalendar.component.tsx b/src/components/ui/calendar/baseCalendar.component.tsx
index 33b7e4c85..eeae4d5d3 100644
--- a/src/components/ui/calendar/baseCalendar.component.tsx
+++ b/src/components/ui/calendar/baseCalendar.component.tsx
@@ -36,17 +36,25 @@ import {
 } from './type';
 import { TranslationWidth } from './i18n/type';
 import { DateService } from './service/date.service';
-import { NativeDateService } from './service/nativeDate.service';
 import {
   CalendarDataService,
   DateBatch,
 } from './service/calendarData.service';
 
+export interface DerivedCalendarProps<D = Date> extends BaseCalendarProps<D> {
+  createDates: (date: D) => DateBatch<D>;
+  selectedDate: () => D | undefined;
+  onDateSelect: (item: D) => void;
+  isDateSelected: (date: D) => boolean;
+  shouldUpdateDate: (props: CalendarPickerCellProps<D>, nextProps: CalendarPickerCellProps<D>) => boolean;
+}
+
 export interface BaseCalendarProps<D = Date> extends ViewProps {
   min?: D;
   max?: D;
   initialVisibleDate?: D;
   dateService?: DateService<D>;
+  dataService?: CalendarDataService<D>;
   boundingMonth?: boolean;
   startView?: CalendarViewMode;
   title?: (datePickerDate: D, monthYearPickerDate: D, viewMode: CalendarViewMode) => string;
@@ -61,68 +69,88 @@ export interface BaseCalendarProps<D = Date> extends ViewProps {
   eva?: EvaProp;
 }
 
-export type BaseCalendarElement<D> = React.ReactElement<BaseCalendarProps<D>>;
-
-interface State<D> {
-  viewMode: CalendarViewMode;
-  visibleDate: D; // is used in date view mode
-  pickerDate: D; // is used in month/year view mode, goal - not to change visibleDate until month has changed
-  // pickerDate equals to visibleDate from start
-  // is auto synchronised with visibleDate on onPickerNavigationPress (open/close month/year picker)
-  // visibleDate is set to pickerDate on onMonthSelect
-}
+export type BaseCalendarElement<D = Date> = React.ReactElement<DerivedCalendarProps<D>>;
 
 const PICKER_ROWS = 4;
 const PICKER_COLUMNS = 3;
 const VIEWS_IN_PICKER: number = PICKER_ROWS * PICKER_COLUMNS;
 
-export abstract class BaseCalendarComponent<P, D = Date> extends React.Component<BaseCalendarProps<D> & P, State<D>> {
+export interface BaseCalendarRef<D = Date> {
+  scrollToToday: () => void;
+  scrollToDate: (date: D) => void;
+  state: State<D>;
+}
+
+interface State<D> {
+  viewMode: CalendarViewMode;
+  visibleDate: D;
+  pickerDate: D;
+}
 
-  static defaultProps: Partial<BaseCalendarProps> = {
-    dateService: new NativeDateService(),
-    boundingMonth: true,
-    startView: CalendarViewModes.DATE,
-  };
+function BaseCalendarComponent<D = Date>(
+  {
+    dateService,
+    dataService,
+    boundingMonth = true,
+    startView = CalendarViewModes.DATE,
+    ...props
+  }: DerivedCalendarProps<D>,
+  ref: React.RefObject<BaseCalendarRef<D>>
+): BaseCalendarElement<D> {
+  const [viewMode, setViewMode] = React.useState<CalendarViewMode>(startView);
 
-  public state: State<D> = {
-    viewMode: this.props.startView,
-    visibleDate: this.dateService.getMonthStart(this.initialVisibleDate()),
-    pickerDate: this.dateService.getMonthStart(this.initialVisibleDate()),
+  const initialVisibleDate = (): D => {
+    return props.initialVisibleDate || props.selectedDate() || dateService.today();
   };
 
-  protected dataService: CalendarDataService<D> = new CalendarDataService(this.dateService);
+  // is used in date view mode
+  const [
+    visibleDate,
+    setVisibleDate,
+  ] = React.useState(dateService.getMonthStart(initialVisibleDate()));
 
-  protected get dateService(): DateService<D> {
-    return this.props.dateService;
-  }
+  // is used in month/year view mode, goal - not to change visibleDate until month has changed
+  const [pickerDate, setPickerDate,
+  ] = React.useState(dateService.getMonthStart(initialVisibleDate()));
 
-  private get min(): D {
-    return this.props.min || this.dateService.getYearStart(this.dateService.today());
-  }
+  // pickerDate equals to visibleDate from start
+  // is auto synchronised with visibleDate on onPickerNavigationPress (open/close month/year picker)
+  // visibleDate is set to pickerDate on onMonthSelect
+
+  const min = (): D => {
+    return props.min || dateService.getYearStart(dateService.today());
+  };
 
-  private get max(): D {
-    return this.props.max || this.dateService.getYearEnd(this.dateService.today());
-  }
+  const max = (): D => {
+    return props.max || dateService.getYearEnd(dateService.today());
+  };
 
-  public scrollToToday = (): void => {
-    this.setState({
-      viewMode: CalendarViewModes.DATE,
-      visibleDate: this.dateService.today(),
-      pickerDate: this.dateService.today(),
-    });
+  const scrollToToday = (): void => {
+    setViewMode(CalendarViewModes.DATE);
+    setVisibleDate(dateService.today());
+    setPickerDate(dateService.today());
   };
 
-  public scrollToDate = (date: D): void => {
+  const scrollToDate = (date: D): void => {
     if (date) {
-      this.setState({
-        viewMode: CalendarViewModes.DATE,
-        visibleDate: date,
-        pickerDate: date,
-      });
+      setViewMode(CalendarViewModes.DATE);
+      setVisibleDate(date);
+      setPickerDate(date);
     }
   };
 
-  public getCalendarStyle = (source: StyleType): StyleType => {
+  React.useImperativeHandle(ref, () => ({
+    ...ref.current,
+    scrollToToday,
+    scrollToDate,
+    state: {
+      pickerDate,
+      viewMode,
+      visibleDate,
+    },
+  }));
+
+  const getCalendarStyle = (source: StyleType): StyleType => {
     return {
       container: {
         width: source.width,
@@ -159,111 +187,84 @@ export abstract class BaseCalendarComponent<P, D = Date> extends React.Component
     };
   };
 
-  public isDayDisabled = ({ date }: CalendarDateInfo<D>): boolean => {
-    const minDayStart: D = this.dateService.createDate(
-      this.dateService.getYear(this.min),
-      this.dateService.getMonth(this.min),
-      this.dateService.getDate(this.min),
+  const isDayDisabled = ({ date }: CalendarDateInfo<D>): boolean => {
+    const minDayStart: D = dateService.createDate(
+      dateService.getYear(min()),
+      dateService.getMonth(min()),
+      dateService.getDate(min()),
     );
 
-    const maxDayStart: D = this.dateService.createDate(
-      this.dateService.getYear(this.max),
-      this.dateService.getMonth(this.max),
-      this.dateService.getDate(this.max),
+    const maxDayStart: D = dateService.createDate(
+      dateService.getYear(max()),
+      dateService.getMonth(max()),
+      dateService.getDate(max()),
     );
 
-    const fitsFilter: boolean = this.props.filter && !this.props.filter(date) || false;
+    const fitsFilter: boolean = props.filter && !props.filter(date) || false;
 
-    return !this.dateService.isBetweenIncludingSafe(date, minDayStart, maxDayStart) || fitsFilter;
+    return !dateService.isBetweenIncludingSafe(date, minDayStart, maxDayStart) || fitsFilter;
   };
 
-  public isDayToday = ({ date }: CalendarDateInfo<D>): boolean => {
-    return this.dateService.isSameDaySafe(date, this.dateService.today());
+  const isDayToday = ({ date }: CalendarDateInfo<D>): boolean => {
+    return dateService.isSameDaySafe(date, dateService.today());
   };
 
-  protected abstract createDates(date: D): DateBatch<D>;
-
-  protected abstract selectedDate(): D | undefined;
-
-  protected abstract onDateSelect(item: D): void;
-
-  protected abstract isDateSelected(date: D): boolean;
-
-  protected abstract shouldUpdateDate(props: CalendarPickerCellProps<D>,
-    nextProps: CalendarPickerCellProps<D>): boolean;
-
-  private initialVisibleDate(): D {
-    return this.props.initialVisibleDate || this.selectedDate() || this.dateService.today();
-  }
-
-  private onDaySelect = ({ date }: CalendarDateInfo<D>): void => {
-    this.onDateSelect(date);
+  const onDaySelect = ({ date }: CalendarDateInfo<D>): void => {
+    props.onDateSelect(date);
   };
 
-  private onMonthSelect = ({ date }: CalendarDateInfo<D>): void => {
-    const { pickerDate, viewMode } = this.state;
-    const nextVisibleDate: D = this.dateService.createDate(
-      this.dateService.getYear(pickerDate),
-      this.dateService.getMonth(date),
-      this.dateService.getDate(pickerDate),
+  const onMonthSelect = ({ date }: CalendarDateInfo<D>): void => {
+    const nextVisibleDate: D = dateService.createDate(
+      dateService.getYear(pickerDate),
+      dateService.getMonth(date),
+      dateService.getDate(pickerDate),
     );
 
-    this.setState({
-      viewMode: viewMode.pickNext(),
-      visibleDate: nextVisibleDate,
-      pickerDate: nextVisibleDate,
-    }, () => {
-      this.props.onVisibleDateChange?.(this.state.visibleDate, this.state.viewMode.id);
-    });
-  };
-
-  private onYearSelect = ({ date }: CalendarDateInfo<D>): void => {
-    const { pickerDate, viewMode } = this.state;
-    const nextVisibleDate: D = this.dateService.createDate(
-      this.dateService.getYear(date),
-      this.dateService.getMonth(pickerDate),
-      this.dateService.getDate(pickerDate),
+    setViewMode(viewMode.pickNext());
+    setVisibleDate(nextVisibleDate);
+    setPickerDate(nextVisibleDate);
+    props.onVisibleDateChange?.(nextVisibleDate, viewMode.id);
+  };
+
+  const onYearSelect = ({ date }: CalendarDateInfo<D>): void => {
+    const nextVisibleDate: D = dateService.createDate(
+      dateService.getYear(date),
+      dateService.getMonth(pickerDate),
+      dateService.getDate(pickerDate),
     );
 
-    this.setState({
-      viewMode: viewMode.pickNext(),
-      pickerDate: nextVisibleDate,
-    });
+    setViewMode(viewMode.pickNext());
+    setPickerDate(nextVisibleDate);
   };
 
-  private onPickerNavigationPress = (): void => {
-    const { viewMode, visibleDate } = this.state;
-    this.setState({
-      viewMode: viewMode.navigationNext(),
-      pickerDate: visibleDate,
-    });
+  const onPickerNavigationPress = (): void => {
+    setViewMode(viewMode.navigationNext());
+    setPickerDate(visibleDate);
   };
 
-  private onHeaderNavigationLeftPress = (): void => {
-    const nextDate = this.createViewModeVisibleDate(-1);
+  const onHeaderNavigationLeftPress = (): void => {
+    const nextDate = createViewModeVisibleDate(-1);
 
-    if (this.state.viewMode.id === CalendarViewModes.DATE.id) {
-      this.setState({ visibleDate: nextDate }, () => {
-        this.props.onVisibleDateChange?.(this.state.visibleDate, this.state.viewMode.id);
-      });
+    if (viewMode.id === CalendarViewModes.DATE.id) {
+      setVisibleDate(nextDate);
+      props.onVisibleDateChange?.(visibleDate, viewMode.id);
     } else {
-      this.setState({ pickerDate: nextDate });
+      setPickerDate(nextDate);
     }
   };
 
-  private onHeaderNavigationRightPress = (): void => {
-    const nextDate = this.createViewModeVisibleDate(1);
+  const onHeaderNavigationRightPress = (): void => {
+    const nextDate = createViewModeVisibleDate(1);
 
-    if (this.state.viewMode.id === CalendarViewModes.DATE.id) {
-      this.setState({ visibleDate: nextDate }, () => {
-        this.props.onVisibleDateChange?.(this.state.visibleDate, this.state.viewMode.id);
-      });
+    if (viewMode.id === CalendarViewModes.DATE.id) {
+      setVisibleDate(nextDate);
+      props.onVisibleDateChange?.(visibleDate, viewMode.id);
     } else {
-      this.setState({ pickerDate: nextDate });
+      setPickerDate(nextDate);
     }
   };
 
-  private getWeekdayStyle = (source: StyleType): StyleType => {
+  const getWeekdayStyle = (source: StyleType): StyleType => {
     return {
       fontSize: source.weekdayTextFontSize,
       fontWeight: source.weekdayTextFontWeight,
@@ -272,71 +273,71 @@ export abstract class BaseCalendarComponent<P, D = Date> extends React.Component
     };
   };
 
-  private isDaySelected = ({ date }: CalendarDateInfo<D>): boolean => {
-    return this.isDateSelected(date);
+  const isDaySelected = ({ date }: CalendarDateInfo<D>): boolean => {
+    return props.isDateSelected(date);
   };
 
-  private isMonthSelected = ({ date }: CalendarDateInfo<D>): boolean => {
-    return this.dateService.isSameMonthSafe(date, this.selectedDate());
+  const isMonthSelected = ({ date }: CalendarDateInfo<D>): boolean => {
+    return dateService.isSameMonthSafe(date, props.selectedDate());
   };
 
-  private isYearSelected = ({ date }: CalendarDateInfo<D>): boolean => {
-    return this.dateService.isSameYearSafe(date, this.selectedDate());
+  const isYearSelected = ({ date }: CalendarDateInfo<D>): boolean => {
+    return dateService.isSameYearSafe(date, props.selectedDate());
   };
 
-  private isMonthDisabled = ({ date }: CalendarDateInfo<D>): boolean => {
-    const minMonthStart: D = this.dateService.getMonthStart(this.min);
-    const maxMonthStart: D = this.dateService.getMonthStart(this.max);
+  const isMonthDisabled = ({ date }: CalendarDateInfo<D>): boolean => {
+    const minMonthStart: D = dateService.getMonthStart(min());
+    const maxMonthStart: D = dateService.getMonthStart(max());
 
-    return !this.dateService.isBetweenIncludingSafe(date, minMonthStart, maxMonthStart);
+    return !dateService.isBetweenIncludingSafe(date, minMonthStart, maxMonthStart);
   };
 
-  private isYearDisabled = ({ date }: CalendarDateInfo<D>): boolean => {
-    const minYearStart: D = this.dateService.getYearStart(this.min);
-    const maxYearStart: D = this.dateService.getYearEnd(this.max);
+  const isYearDisabled = ({ date }: CalendarDateInfo<D>): boolean => {
+    const minYearStart: D = dateService.getYearStart(min());
+    const maxYearStart: D = dateService.getYearEnd(max());
 
-    return !this.dateService.isBetweenIncludingSafe(date, minYearStart, maxYearStart);
+    return !dateService.isBetweenIncludingSafe(date, minYearStart, maxYearStart);
   };
 
-  private isMonthToday = (date: CalendarDateInfo<D>): boolean => {
-    return this.dateService.isSameMonthSafe(date.date, this.dateService.today());
+  const isMonthToday = (date: CalendarDateInfo<D>): boolean => {
+    return dateService.isSameMonthSafe(date.date, dateService.today());
   };
 
-  private isYearToday = ({ date }: CalendarDateInfo<D>): boolean => {
-    return this.dateService.isSameYearSafe(date, this.dateService.today());
+  const isYearToday = ({ date }: CalendarDateInfo<D>): boolean => {
+    return dateService.isSameYearSafe(date, dateService.today());
   };
 
-  private isHeaderNavigationAllowed = (): boolean => {
-    return this.state.viewMode.id !== CalendarViewModes.MONTH.id;
+  const isHeaderNavigationAllowed = (): boolean => {
+    return viewMode.id !== CalendarViewModes.MONTH.id;
   };
 
-  private createViewModeVisibleDate = (page: number): D => {
-    switch (this.state.viewMode.id) {
+  const createViewModeVisibleDate = (page: number): D => {
+    switch (viewMode.id) {
       case CalendarViewModes.DATE.id: {
-        return this.dateService.addMonth(this.state.visibleDate, page);
+        return dateService.addMonth(visibleDate, page);
       }
       case CalendarViewModes.MONTH.id: {
-        return this.dateService.addYear(this.state.pickerDate, page);
+        return dateService.addYear(pickerDate, page);
       }
       case CalendarViewModes.YEAR.id: {
-        return this.dateService.addYear(this.state.pickerDate, VIEWS_IN_PICKER * page);
+        return dateService.addYear(pickerDate, VIEWS_IN_PICKER * page);
       }
       default: return;
     }
   };
 
-  private createViewModeHeaderTitle = (visibleDate: D, pickerDate: D, viewMode: CalendarViewMode): string => {
-    switch (viewMode.id) {
+  const createViewModeHeaderTitle = (newVisibleDate: D, newPickerDate: D, newViewMode: CalendarViewMode): string => {
+    switch (newViewMode.id) {
       case CalendarViewModes.DATE.id: {
-        const month: string = this.props.dateService.getMonthName(visibleDate, TranslationWidth.LONG);
-        const year: number = this.props.dateService.getYear(visibleDate);
+        const month: string = dateService.getMonthName(newVisibleDate, TranslationWidth.LONG);
+        const year: number = dateService.getYear(newVisibleDate);
         return `${month} ${year}`;
       }
       case CalendarViewModes.MONTH.id: {
-        return `${this.dateService.getYear(pickerDate)}`;
+        return `${dateService.getYear(newPickerDate)}`;
       }
       case CalendarViewModes.YEAR.id: {
-        const minDateFormat: number = this.dateService.getYear(pickerDate);
+        const minDateFormat: number = dateService.getYear(newPickerDate);
         const maxDateFormat: number = minDateFormat + VIEWS_IN_PICKER - 1;
 
         return `${minDateFormat} - ${maxDateFormat}`;
@@ -345,168 +346,175 @@ export abstract class BaseCalendarComponent<P, D = Date> extends React.Component
     }
   };
 
-  private renderDayIfNeeded = (item: CalendarDateInfo<D>, style: StyleType): CalendarDateContentElement => {
-    const shouldRender: boolean = !item.bounding || this.props.boundingMonth;
+  const renderDayIfNeeded = (item: CalendarDateInfo<D>, style: StyleType): CalendarDateContentElement => {
+    const shouldRender: boolean = !item.bounding || boundingMonth;
 
     if (shouldRender) {
-      const renderSelector = this.props.renderDay || this.renderDayElement;
+      const renderSelector = props.renderDay || renderDayElement;
       return renderSelector(item, style);
     }
 
     return null;
   };
 
-  private renderWeekdayElement = (weekday: string, index: number): CalendarDateContentElement => {
+  const renderWeekdayElement = (weekday: string, index: number): CalendarDateContentElement => {
     return (
       <CalendarDateContent
         key={index}
-        textStyle={this.getWeekdayStyle(this.props.eva.style)}
+        textStyle={getWeekdayStyle(props.eva.style)}
       >
         {weekday}
       </CalendarDateContent>
     );
   };
 
-  private renderDayElement = ({ date }: CalendarDateInfo<D>, evaStyle): CalendarDateContentElement => {
+  const renderDayElement = ({ date }: CalendarDateInfo<D>, evaStyle: StyleType): CalendarDateContentElement => {
     return (
       <CalendarDateContent
         style={evaStyle.container}
         textStyle={evaStyle.text}
       >
-        {this.dateService.getDate(date)}
+        {dateService.getDate(date)}
       </CalendarDateContent>
     );
   };
 
-  private renderMonthElement = ({ date }: CalendarDateInfo<D>, evaStyle): CalendarDateContentElement => {
+  const renderMonthElement = ({ date }: CalendarDateInfo<D>, evaStyle: StyleType): CalendarDateContentElement => {
     return (
       <CalendarDateContent
         style={evaStyle.container}
         textStyle={evaStyle.text}
       >
-        {this.dateService.getMonthName(date, TranslationWidth.SHORT)}
+        {dateService.getMonthName(date, TranslationWidth.SHORT)}
       </CalendarDateContent>
     );
   };
 
-  private renderYearElement = ({ date }: CalendarDateInfo<D>, evaStyle): CalendarDateContentElement => {
+  const renderYearElement = ({ date }: CalendarDateInfo<D>, evaStyle: StyleType): CalendarDateContentElement => {
     return (
       <CalendarDateContent
         style={evaStyle.container}
         textStyle={evaStyle.text}
       >
-        {this.dateService.getYear(date)}
+        {dateService.getYear(date)}
       </CalendarDateContent>
     );
   };
 
-  private renderDayPickerElement = (date: D, evaStyle): React.ReactElement => {
+  const renderDayPickerElement = (date: D, evaStyle: StyleType): React.ReactElement => {
     return (
       <>
         <CalendarMonthHeader
           style={evaStyle.daysHeaderContainer}
-          data={this.dateService.getDayOfWeekNames()}
+          data={dateService.getDayOfWeekNames()}
         >
-          {this.renderWeekdayElement}
+          {renderWeekdayElement}
         </CalendarMonthHeader>
         <Divider style={evaStyle.divider} />
         <CalendarPicker
           rowStyle={evaStyle.row}
-          data={this.createDates(date)}
-          onSelect={this.onDaySelect}
-          isItemSelected={this.isDaySelected}
-          isItemDisabled={this.isDayDisabled}
-          isItemToday={this.isDayToday}
-          shouldItemUpdate={this.shouldUpdateDate}
+          data={props.createDates(date)}
+          onSelect={onDaySelect}
+          isItemSelected={isDaySelected}
+          isItemDisabled={isDayDisabled}
+          isItemToday={isDayToday}
+          shouldItemUpdate={props.shouldUpdateDate}
         >
-          {this.renderDayIfNeeded}
+          {renderDayIfNeeded}
         </CalendarPicker>
       </>
     );
   };
 
-  private renderMonthPickerElement = (date: D, evaStyle): CalendarPickerElement<D> => {
+  const renderMonthPickerElement = (date: D, evaStyle: StyleType): CalendarPickerElement<D> => {
     return (
       <CalendarPicker
         rowStyle={evaStyle.row}
-        data={this.dataService.createMonthPickerData(date, PICKER_ROWS, PICKER_COLUMNS)}
-        onSelect={this.onMonthSelect}
-        isItemSelected={this.isMonthSelected}
-        isItemDisabled={this.isMonthDisabled}
-        isItemToday={this.isMonthToday}
+        data={dataService.createMonthPickerData(date, PICKER_ROWS, PICKER_COLUMNS)}
+        onSelect={onMonthSelect}
+        isItemSelected={isMonthSelected}
+        isItemDisabled={isMonthDisabled}
+        isItemToday={isMonthToday}
       >
-        {this.props.renderMonth || this.renderMonthElement}
+        {props.renderMonth || renderMonthElement}
       </CalendarPicker>
     );
   };
 
-  private renderYearPickerElement = (date: D, style: StyleType): CalendarPickerElement<D> => {
+  const renderYearPickerElement = (date: D, style: StyleType): CalendarPickerElement<D> => {
     return (
       <CalendarPicker
         rowStyle={style.row}
-        data={this.dataService.createYearPickerData(date, PICKER_ROWS, PICKER_COLUMNS)}
-        onSelect={this.onYearSelect}
-        isItemSelected={this.isYearSelected}
-        isItemDisabled={this.isYearDisabled}
-        isItemToday={this.isYearToday}
+        data={dataService.createYearPickerData(date, PICKER_ROWS, PICKER_COLUMNS)}
+        onSelect={onYearSelect}
+        isItemSelected={isYearSelected}
+        isItemDisabled={isYearDisabled}
+        isItemToday={isYearToday}
       >
-        {this.props.renderYear || this.renderYearElement}
+        {props.renderYear || renderYearElement}
       </CalendarPicker>
     );
   };
 
-  private renderPickerElement = (style: StyleType): React.ReactNode => {
-    switch (this.state.viewMode.id) {
+  const renderPickerElement = (style: StyleType): React.ReactNode => {
+    switch (viewMode.id) {
       case CalendarViewModes.DATE.id:
-        return this.renderDayPickerElement(this.state.visibleDate, style);
+        return renderDayPickerElement(visibleDate, style);
       case CalendarViewModes.MONTH.id:
-        return this.renderMonthPickerElement(this.state.pickerDate, style);
+        return renderMonthPickerElement(pickerDate, style);
       case CalendarViewModes.YEAR.id:
-        return this.renderYearPickerElement(this.state.pickerDate, style);
+        return renderYearPickerElement(pickerDate, style);
       default: return;
     }
   };
 
-  private renderFooterElement = (): React.ReactElement => {
-    if (this.props.renderFooter) {
-      return this.props.renderFooter();
+  const renderFooterElement = (): React.ReactElement => {
+    if (props.renderFooter) {
+      return props.renderFooter();
     }
     return null;
   };
 
-  private renderHeaderElement = (evaStyle): CalendarHeaderElement => {
-    const titleSelector = this.props.title || this.createViewModeHeaderTitle;
+
+  const renderHeaderElement = (evaStyle: StyleType): CalendarHeaderElement => {
+    const titleSelector = props.title || createViewModeHeaderTitle;
 
     return (
       <CalendarHeader
-        viewModeId={this.state.viewMode.id}
+        viewModeId={viewMode.id}
         style={evaStyle.headerContainer}
-        title={titleSelector(this.state.visibleDate, this.state.pickerDate, this.state.viewMode)}
+        title={titleSelector(visibleDate, pickerDate, viewMode)}
         titleStyle={evaStyle.title}
         iconStyle={evaStyle.icon}
-        lateralNavigationAllowed={this.isHeaderNavigationAllowed()}
-        onTitlePress={this.onPickerNavigationPress}
-        onNavigationLeftPress={this.onHeaderNavigationLeftPress}
-        onNavigationRightPress={this.onHeaderNavigationRightPress}
-        arrowLeftComponent={this.props.renderArrowLeft}
-        arrowRightComponent={this.props.renderArrowRight}
+        lateralNavigationAllowed={isHeaderNavigationAllowed()}
+        onTitlePress={onPickerNavigationPress}
+        onNavigationLeftPress={onHeaderNavigationLeftPress}
+        onNavigationRightPress={onHeaderNavigationRightPress}
+        arrowLeftComponent={props.renderArrowLeft}
+        arrowRightComponent={props.renderArrowRight}
       />
     );
   };
 
-  public render(): React.ReactElement<ViewProps> {
-    const { eva, style, ...viewProps } = this.props;
-    const evaStyle = this.getCalendarStyle(eva.style);
+  const { eva, style, ...viewProps } = props;
+  const evaStyle = getCalendarStyle(eva.style);
 
-    return (
-      <View
-        {...viewProps}
-        style={[evaStyle.container, style]}
-      >
-        {this.renderHeaderElement(evaStyle)}
-        {this.renderPickerElement(evaStyle)}
-        {this.renderFooterElement()}
-      </View>
-    );
-  }
+  return (
+    <View
+      {...viewProps}
+      style={[evaStyle.container, style]}
+    >
+      {renderHeaderElement(evaStyle)}
+      {renderPickerElement(evaStyle)}
+      {renderFooterElement()}
+    </View>
+  );
 }
+
+BaseCalendarComponent.displayName = 'BaseCalendarComponent';
+
+const component = React.forwardRef(BaseCalendarComponent);
+
+export {
+  component as BaseCalendarComponent,
+};
diff --git a/src/components/ui/calendar/calendar.component.tsx b/src/components/ui/calendar/calendar.component.tsx
index 9f5364d22..f27fc75e4 100644
--- a/src/components/ui/calendar/calendar.component.tsx
+++ b/src/components/ui/calendar/calendar.component.tsx
@@ -4,6 +4,7 @@
  * Licensed under the MIT License. See License.txt in the project root for license information.
  */
 
+import { DateService, NativeDateService } from '@ui-kitten/components';
 import React from 'react';
 import {
   styled,
@@ -12,9 +13,10 @@ import {
 import {
   BaseCalendarComponent,
   BaseCalendarProps,
+  BaseCalendarRef,
 } from './baseCalendar.component';
 import { CalendarPickerCellProps } from './components/picker/calendarPickerCell.component';
-import { DateBatch } from './service/calendarData.service';
+import { CalendarDataService, DateBatch } from './service/calendarData.service';
 
 export interface CalendarProps<D = Date> extends StyledComponentProps, BaseCalendarProps<D> {
   date?: D;
@@ -23,6 +25,10 @@ export interface CalendarProps<D = Date> extends StyledComponentProps, BaseCalen
 
 export type CalendarElement<D = Date> = React.ReactElement<CalendarProps<D>>;
 
+export type CalendarRef<D = Date> = BaseCalendarRef<D> & {
+  dataService: CalendarDataService<D>;
+};
+
 /**
  * Calendar provides a simple way to select a date.
  *
@@ -127,47 +133,46 @@ export type CalendarElement<D = Date> = React.ReactElement<CalendarProps<D>>;
  * @overview-example CalendarTheming
  * Styling of the calendar is possible with [configuring a custom theme](guides/branding).
  */
-
-@styled('Calendar')
-export class Calendar<D = Date> extends BaseCalendarComponent<CalendarProps<D>, D> {
-
-  constructor(props: CalendarProps<D>) {
-    super(props);
-
-    this.createDates = this.createDates.bind(this);
-    this.selectedDate = this.selectedDate.bind(this);
-    this.onDateSelect = this.onDateSelect.bind(this);
-    this.isDateSelected = this.isDateSelected.bind(this);
-    this.shouldUpdateDate = this.shouldUpdateDate.bind(this);
-  }
-
-  // BaseCalendarComponent
-
-  protected createDates(date: D): DateBatch<D> {
-    return this.dataService.createDayPickerData(date);
-  }
-
-  protected selectedDate(): D | undefined {
-    return this.props.date;
-  }
-
-  protected onDateSelect(date: D): void {
-    this.props.onSelect?.(date);
-  }
-
-  protected isDateSelected(date: D): boolean {
-    return this.dateService.isSameDaySafe(date, this.selectedDate());
-  }
-
-  protected shouldUpdateDate(props: CalendarPickerCellProps<D>, nextProps: CalendarPickerCellProps<D>): boolean {
-    const dateChanged: boolean = this.dateService.compareDatesSafe(props.date.date, nextProps.date.date) !== 0;
+function Calendar <D = Date> (
+  props: CalendarProps<D>,
+  ref: React.RefObject<CalendarRef<D>>,
+): CalendarElement<D> {
+  const dateService = props.dateService ?? new NativeDateService() as unknown as DateService<D>;
+  const dataService: CalendarDataService<D> = new CalendarDataService(dateService);
+
+  React.useImperativeHandle(ref, () => ({
+    ...ref.current,
+    dataService,
+  }), [dataService]);
+
+  const createDates = (date: D): DateBatch<D> => {
+    return dataService.createDayPickerData(date);
+  };
+
+  const selectedDate = (): D | undefined => {
+    return props.date;
+  };
+
+  const onDateSelect = (date: D): void => {
+    props.onSelect?.(date);
+  };
+
+  const isDateSelected = (date: D): boolean => {
+    return dateService.isSameDaySafe(date, selectedDate());
+  };
+
+  const shouldUpdateDate = (prevProps: CalendarPickerCellProps<D>, nextProps: CalendarPickerCellProps<D>): boolean => {
+    const dateChanged: boolean = dateService.compareDatesSafe(
+      prevProps.date.date,
+      nextProps.date.date,
+    ) !== 0;
 
     if (dateChanged) {
       return true;
     }
 
-    const selectionChanged: boolean = props.selected !== nextProps.selected;
-    const disablingChanged: boolean = props.disabled !== nextProps.disabled;
+    const selectionChanged: boolean = prevProps.selected !== nextProps.selected;
+    const disablingChanged: boolean = prevProps.disabled !== nextProps.disabled;
 
     const value: boolean = selectionChanged || disablingChanged;
 
@@ -175,6 +180,26 @@ export class Calendar<D = Date> extends BaseCalendarComponent<CalendarProps<D>,
       return true;
     }
 
-    return props.eva.theme !== nextProps.eva.theme;
-  }
+    return prevProps.eva.theme !== nextProps.eva.theme;
+  };
+
+  return (
+    <BaseCalendarComponent
+      {...props}
+      dateService={dateService}
+      dataService={dataService}
+      ref={ref}
+      createDates={createDates}
+      selectedDate={selectedDate}
+      onDateSelect={onDateSelect}
+      isDateSelected={isDateSelected}
+      shouldUpdateDate={shouldUpdateDate}
+    />
+  );
 }
+
+const component = styled('Calendar')(React.forwardRef(Calendar));
+
+export {
+  component as Calendar,
+};
diff --git a/src/components/ui/calendar/calendar.spec.tsx b/src/components/ui/calendar/calendar.spec.tsx
index 5a34f4ef6..16dda81fd 100644
--- a/src/components/ui/calendar/calendar.spec.tsx
+++ b/src/components/ui/calendar/calendar.spec.tsx
@@ -22,7 +22,7 @@ import {
 import { ApplicationProvider } from '../../theme';
 import {
   Calendar,
-  CalendarProps,
+  CalendarProps, CalendarRef,
 } from './calendar.component';
 import { CalendarViewModes } from './type';
 import { MomentDateService } from '@ui-kitten/moment';
@@ -46,7 +46,7 @@ describe('@calendar: component checks', () => {
 
   const TestCalendar = React.forwardRef((
     props: Partial<CalendarProps<Date | Moment>>,
-    ref: React.Ref<Calendar>,
+    ref: React.Ref<CalendarRef>,
   ) => {
 
     const [date, setDate] = React.useState<Date | Moment>(props.date);
@@ -125,7 +125,7 @@ describe('@calendar: component checks', () => {
   });
 
   it('should be rendered with view passed to startView prop', () => {
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     render(
       <TestCalendar
         ref={componentRef}
@@ -137,7 +137,7 @@ describe('@calendar: component checks', () => {
   });
 
   it('should change month to next when navigation button pressed', () => {
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     const component = render(
       <TestCalendar ref={componentRef} />,
     );
@@ -153,7 +153,7 @@ describe('@calendar: component checks', () => {
   });
 
   it('should change month to previous when navigation button pressed', () => {
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     const component = render(
       <TestCalendar ref={componentRef} />,
     );
@@ -169,7 +169,7 @@ describe('@calendar: component checks', () => {
   });
 
   it('should change year to next when navigation button pressed', () => {
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     const component = render(
       <TestCalendar
         ref={componentRef}
@@ -189,7 +189,7 @@ describe('@calendar: component checks', () => {
   });
 
   it('should change year to previous when navigation button pressed', () => {
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     const component = render(
       <TestCalendar
         ref={componentRef}
@@ -210,7 +210,7 @@ describe('@calendar: component checks', () => {
 
   it('should show the selected date on load provided by date prop', () => {
     const date = new Date(2021, 2, 1);
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     render(
       <TestCalendar
         ref={componentRef}
@@ -225,7 +225,7 @@ describe('@calendar: component checks', () => {
 
   it('should show the specific date on load provided by initialVisibleDate prop', () => {
     const initialDate = new Date(2021, 2, 1);
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     render(
       <TestCalendar
         ref={componentRef}
@@ -240,7 +240,7 @@ describe('@calendar: component checks', () => {
   });
 
   it('should scroll to current month when scrollToToday called', () => {
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     render(
       <TestCalendar
         ref={componentRef}
@@ -255,7 +255,7 @@ describe('@calendar: component checks', () => {
 
   it('should scroll to the specific date when scrollToDate called', () => {
     const dateToScroll = new Date(2021, 2, 1);
-    const componentRef = React.createRef<Calendar>();
+    const componentRef = React.createRef<CalendarRef>();
     render(
       <TestCalendar
         ref={componentRef}
diff --git a/src/components/ui/calendar/rangeCalendar.component.tsx b/src/components/ui/calendar/rangeCalendar.component.tsx
index 7cf0261d5..98f106821 100644
--- a/src/components/ui/calendar/rangeCalendar.component.tsx
+++ b/src/components/ui/calendar/rangeCalendar.component.tsx
@@ -4,6 +4,7 @@
  * Licensed under the MIT License. See License.txt in the project root for license information.
  */
 
+import { DateService, NativeDateService } from '@ui-kitten/components';
 import React from 'react';
 import {
   styled,
@@ -12,9 +13,10 @@ import {
 import {
   BaseCalendarComponent,
   BaseCalendarProps,
+  BaseCalendarRef,
 } from './baseCalendar.component';
 import { CalendarPickerCellProps } from './components/picker/calendarPickerCell.component';
-import { DateBatch } from './service/calendarData.service';
+import { CalendarDataService, DateBatch } from './service/calendarData.service';
 import { RangeDateService } from './service/rangeDate.service';
 import { CalendarRange } from './type';
 
@@ -25,6 +27,8 @@ export interface RangeCalendarProps<D = Date> extends StyledComponentProps, Base
 
 export type RangeCalendarElement<D = Date> = React.ReactElement<RangeCalendarProps<D>>;
 
+export type RangeCalendarRef<D = Date> = BaseCalendarRef<D>;
+
 /**
  * Range Calendar provides a simple way to select a date range.
  *
@@ -109,59 +113,53 @@ export type RangeCalendarElement<D = Date> = React.ReactElement<RangeCalendarPro
  * }
  * ```
  */
-@styled('Calendar')
-export class RangeCalendar<D = Date> extends BaseCalendarComponent<RangeCalendarProps<D>, D> {
-
-  static defaultProps: Partial<RangeCalendarProps> = {
-    ...BaseCalendarComponent.defaultProps,
-    range: {},
+function RangeCalendar <D = Date> (
+  {
+    range = {},
+    ...props
+  }: RangeCalendarProps<D>,
+  ref: React.RefObject<RangeCalendarRef<D>>,
+): RangeCalendarElement {
+  const dateService = props.dateService ?? new NativeDateService() as unknown as DateService<D>;
+  const rangeDateService: RangeDateService<D> = new RangeDateService(dateService);
+  const dataService: CalendarDataService<D> = new CalendarDataService(dateService);
+
+  React.useImperativeHandle(ref, () => ({
+    ...ref.current,
+    dataService,
+  }), [dataService]);
+
+  const createDates = (date: D): DateBatch<D> => {
+    return dataService.createDayPickerData(date, range);
   };
 
-  private rangeDateService: RangeDateService<D> = new RangeDateService(this.dateService);
-
-  constructor(props: RangeCalendarProps<D>) {
-    super(props);
-
-    this.createDates = this.createDates.bind(this);
-    this.selectedDate = this.selectedDate.bind(this);
-    this.onDateSelect = this.onDateSelect.bind(this);
-    this.isDateSelected = this.isDateSelected.bind(this);
-    this.shouldUpdateDate = this.shouldUpdateDate.bind(this);
-  }
-
-  // BaseCalendarComponent
-
-  protected createDates(date: D): DateBatch<D> {
-    return this.dataService.createDayPickerData(date, this.props.range);
-  }
-
-  protected selectedDate(): D | undefined {
-    return this.props.range?.startDate;
-  }
+  const selectedDate = (): D | undefined => {
+    return range.startDate;
+  };
 
-  protected onDateSelect(date: D): void {
-    if (this.props.onSelect) {
-      const range: CalendarRange<D> = this.rangeDateService.createRange(this.props.range, date);
-      this.props.onSelect(range);
+  const onDateSelect = (date: D): void => {
+    if (props.onSelect) {
+      const calendarRange: CalendarRange<D> = rangeDateService.createRange(range, date);
+      props.onSelect(calendarRange);
     }
-  }
+  };
 
-  protected isDateSelected(): boolean {
+  const isDateSelected = (): boolean => {
     return false;
-  }
+  };
 
-  protected shouldUpdateDate(props: CalendarPickerCellProps<D>, nextProps: CalendarPickerCellProps<D>): boolean {
-    const dateChanged: boolean = this.dateService.compareDatesSafe(props.date.date, nextProps.date.date) !== 0;
+  const shouldUpdateDate = (prevProps: CalendarPickerCellProps<D>, nextProps: CalendarPickerCellProps<D>): boolean => {
+    const dateChanged: boolean = dateService.compareDatesSafe(prevProps.date.date, nextProps.date.date) !== 0;
 
     if (dateChanged) {
       return true;
     }
 
-    const selectionChanged: boolean = props.selected !== nextProps.selected;
-    const disablingChanged: boolean = props.disabled !== nextProps.disabled;
-    const rangeChanged: boolean = props.range !== nextProps.range;
-    const rangeStartPlaceChanged: boolean = props.firstRangeItem !== nextProps.firstRangeItem;
-    const rangeEndPlaceChanged: boolean = props.lastRangeItem !== nextProps.lastRangeItem;
+    const selectionChanged: boolean = prevProps.selected !== nextProps.selected;
+    const disablingChanged: boolean = prevProps.disabled !== nextProps.disabled;
+    const rangeChanged: boolean = prevProps.range !== nextProps.range;
+    const rangeStartPlaceChanged: boolean = prevProps.firstRangeItem !== nextProps.firstRangeItem;
+    const rangeEndPlaceChanged: boolean = prevProps.lastRangeItem !== nextProps.lastRangeItem;
 
     const shouldUpdate: boolean =
       selectionChanged ||
@@ -174,6 +172,26 @@ export class RangeCalendar<D = Date> extends BaseCalendarComponent<RangeCalendar
       return true;
     }
 
-    return props.eva.theme !== nextProps.eva.theme;
-  }
+    return prevProps.eva.theme !== nextProps.eva.theme;
+  };
+
+  return (
+    <BaseCalendarComponent
+      {...props}
+      dateService={dateService}
+      dataService={dataService}
+      ref={ref}
+      createDates={createDates}
+      selectedDate={selectedDate}
+      onDateSelect={onDateSelect}
+      isDateSelected={isDateSelected}
+      shouldUpdateDate={shouldUpdateDate}
+    />
+  );
 }
+
+const Component = styled('Calendar')(React.forwardRef(RangeCalendar));
+
+export {
+  Component as RangeCalendar,
+};
diff --git a/src/components/ui/calendar/rangeCalendar.spec.tsx b/src/components/ui/calendar/rangeCalendar.spec.tsx
index ccfe79010..dc554a354 100644
--- a/src/components/ui/calendar/rangeCalendar.spec.tsx
+++ b/src/components/ui/calendar/rangeCalendar.spec.tsx
@@ -10,7 +10,7 @@ import {
 import { ApplicationProvider } from '../../theme';
 import {
   RangeCalendar,
-  RangeCalendarProps,
+  RangeCalendarProps, RangeCalendarRef,
 } from './rangeCalendar.component';
 import { CalendarRange } from './type';
 import { TouchableOpacity } from 'react-native';
@@ -38,7 +38,7 @@ describe('@range-calendar: component checks', () => {
 
   const TestRangeCalendar = React.forwardRef((
     props: Partial<RangeCalendarProps>,
-    ref: React.Ref<RangeCalendar>) => {
+    ref: React.Ref<RangeCalendarRef>) => {
 
     const [range, setRange] = React.useState<CalendarRange<Date>>(props.range || {});
 
@@ -122,7 +122,7 @@ describe('@range-calendar: component checks', () => {
 
   it('should show startDate of the selected range on load provided by range prop', () => {
     const date = new Date(2021, 2, 1);
-    const componentRef = React.createRef<RangeCalendar>();
+    const componentRef = React.createRef<RangeCalendarRef>();
     render(
       <TestRangeCalendar
         ref={componentRef}
diff --git a/src/components/ui/datepicker/baseDatepicker.component.tsx b/src/components/ui/datepicker/baseDatepicker.component.tsx
index c6a99f37e..b5e12f3bb 100644
--- a/src/components/ui/datepicker/baseDatepicker.component.tsx
+++ b/src/components/ui/datepicker/baseDatepicker.component.tsx
@@ -12,7 +12,6 @@ import {
   StyleSheet,
   TouchableOpacityProps,
   View,
-  ViewProps,
   ViewStyle,
 } from 'react-native';
 import {
@@ -26,252 +25,186 @@ import {
 import {
   Interaction,
   StyledComponentProps,
-  StyleType,
 } from '../../theme';
 import { BaseCalendarProps } from '../calendar/baseCalendar.component';
 import { CalendarElement } from '../calendar/calendar.component';
 import { RangeCalendarElement } from '../calendar/rangeCalendar.component';
-import { NativeDateService } from '../calendar/service/nativeDate.service';
 import { Popover } from '../popover/popover.component';
 import {
   PopoverPlacement,
   PopoverPlacements,
 } from '../popover/type';
 import { TextProps } from '../text/text.component';
+import { getComponentStyle } from './baseDatepicker.utils';
 
 export interface BaseDatepickerProps<D = Date> extends StyledComponentProps,
   TouchableOpacityProps,
   BaseCalendarProps<D> {
-
   controlStyle?: StyleProp<ViewStyle>;
-  label?: RenderProp<TextProps> | React.ReactText;
-  caption?: RenderProp<TextProps> | React.ReactText;
+  label?: RenderProp<TextProps> | string | number;
+  caption?: RenderProp<TextProps> | string | number;
   accessoryLeft?: RenderProp<Partial<ImageProps>>;
   accessoryRight?: RenderProp<Partial<ImageProps>>;
   status?: EvaStatus;
   size?: EvaInputSize;
-  placeholder?: RenderProp<TextProps> | React.ReactText;
+  placeholder?: RenderProp<TextProps> | string | number;
   placement?: PopoverPlacement | string;
   backdropStyle?: StyleProp<ViewStyle>;
   onFocus?: () => void;
   onBlur?: () => void;
 }
 
-interface State {
-  visible: boolean;
+interface DerivedDatepickerProps<D = Date> extends BaseDatepickerProps<D> {
+  children: CalendarElement<D> | RangeCalendarElement<D>;
+  getComponentTitle: () => RenderProp<TextProps> | string | number;
+  clear: () => void;
 }
 
-export abstract class BaseDatepickerComponent<P, D = Date> extends React.Component<BaseDatepickerProps<D> & P, State> {
+export interface BaseDatepickerRef {
+  focus: () => void;
+  blur: () => void;
+  isFocused: () => boolean;
+}
 
-  static defaultProps: Partial<BaseDatepickerProps> = {
-    dateService: new NativeDateService(),
-    placeholder: 'dd/mm/yyyy',
-    placement: PopoverPlacements.BOTTOM_START,
-  };
+function BaseDatepickerComponent<D = Date>(
+  props: DerivedDatepickerProps<D>,
+  ref: React.RefObject<BaseDatepickerRef>,
+): React.ReactElement<DerivedDatepickerProps<D>> {
+  const {
+    eva,
+    style,
+    testID,
+    backdropStyle,
+    label,
+    caption,
+    placement = PopoverPlacements.BOTTOM_START,
+    onFocus,
+    onBlur,
+    getComponentTitle,
+    children,
+  } = props;
+  const evaStyle = getComponentStyle(eva.style);
 
-  public state: State = {
-    visible: false,
-  };
+  const [visible, setVisible] = React.useState(false);
 
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  protected calendarRef = React.createRef<any>();
-
-  public scrollToToday = (): void => {
-    this.calendarRef.current?.scrollToToday();
+  const focus = (): void => {
+    setVisible(true);
+    onPickerVisible();
   };
 
-  public scrollToDate = (date: Date): void => {
-    this.calendarRef.current?.scrollToDate(date);
+  const blur = (): void => {
+    setVisible(false);
+    onPickerInvisible();
   };
 
-  public focus = (): void => {
-    this.setState({ visible: true }, this.onPickerVisible);
+  const isFocused = (): boolean => {
+    return visible;
   };
 
-  public blur = (): void => {
-    this.setState({ visible: false }, this.onPickerInvisible);
-  };
+  React.useImperativeHandle(ref, () => ({
+    ...ref.current,
+    focus,
+    blur,
+    isFocused,
+  }));
 
-  public isFocused = (): boolean => {
-    return this.state.visible;
+  const onPress = (event: GestureResponderEvent): void => {
+    setPickerVisible();
+    props.onPress?.(event);
   };
 
-  public abstract clear(): void;
-
-  protected abstract getComponentTitle(): RenderProp<TextProps> | React.ReactText;
-
-  protected abstract renderCalendar(): CalendarElement<D> | RangeCalendarElement<D>;
-
-  private getComponentStyle = (style: StyleType): StyleType => {
-    const {
-      textMarginHorizontal,
-      textFontFamily,
-      textFontSize,
-      textFontWeight,
-      textColor,
-      placeholderColor,
-      iconWidth,
-      iconHeight,
-      iconMarginHorizontal,
-      iconTintColor,
-      labelColor,
-      labelFontSize,
-      labelMarginBottom,
-      labelFontWeight,
-      labelFontFamily,
-      captionMarginTop,
-      captionColor,
-      captionFontSize,
-      captionFontWeight,
-      captionFontFamily,
-      popoverWidth,
-      ...controlParameters
-    } = style;
-
-    return {
-      control: controlParameters,
-      text: {
-        marginHorizontal: textMarginHorizontal,
-        fontFamily: textFontFamily,
-        fontSize: textFontSize,
-        fontWeight: textFontWeight,
-        color: textColor,
-      },
-      placeholder: {
-        marginHorizontal: textMarginHorizontal,
-        color: placeholderColor,
-      },
-      icon: {
-        width: iconWidth,
-        height: iconHeight,
-        marginHorizontal: iconMarginHorizontal,
-        tintColor: iconTintColor,
-      },
-      label: {
-        color: labelColor,
-        fontSize: labelFontSize,
-        fontFamily: labelFontFamily,
-        marginBottom: labelMarginBottom,
-        fontWeight: labelFontWeight,
-      },
-      captionLabel: {
-        fontSize: captionFontSize,
-        fontWeight: captionFontWeight,
-        fontFamily: captionFontFamily,
-        color: captionColor,
-      },
-      popover: {
-        width: popoverWidth,
-        marginBottom: captionMarginTop,
-      },
-    };
+  const onPressIn = (event: GestureResponderEvent): void => {
+    eva.dispatch([Interaction.ACTIVE]);
+    props.onPressIn?.(event);
   };
 
-  private onPress = (event: GestureResponderEvent): void => {
-    this.setPickerVisible();
-    this.props.onPress?.(event);
+  const onPressOut = (event: GestureResponderEvent): void => {
+    eva.dispatch([]);
+    props.onPressOut?.(event);
   };
 
-  private onPressIn = (event: GestureResponderEvent): void => {
-    this.props.eva.dispatch([Interaction.ACTIVE]);
-    this.props.onPressIn?.(event);
+  const onPickerVisible = (): void => {
+    eva.dispatch([Interaction.ACTIVE]);
+    onFocus?.();
   };
 
-  private onPressOut = (event: GestureResponderEvent): void => {
-    this.props.eva.dispatch([]);
-    this.props.onPressOut?.(event);
+  const onPickerInvisible = (): void => {
+    eva.dispatch([]);
+    onBlur?.();
   };
 
-  private onPickerVisible = (): void => {
-    this.props.eva.dispatch([Interaction.ACTIVE]);
-    this.props.onFocus?.();
+  const setPickerVisible = (): void => {
+    setVisible(true);
+    onPickerVisible();
   };
 
-  private onPickerInvisible = (): void => {
-    this.props.eva.dispatch([]);
-    this.props.onBlur?.();
+  const setPickerInvisible = (): void => {
+    setVisible(false);
+    onPickerInvisible();
   };
 
-  private setPickerVisible = (): void => {
-    this.setState({ visible: true }, this.onPickerVisible);
-  };
-
-  private setPickerInvisible = (): void => {
-    this.setState({ visible: false }, this.onPickerInvisible);
-  };
-
-  private renderInputElement = (props, evaStyle): React.ReactElement => {
+  const renderInputElement = (): React.ReactElement => {
     return (
       <TouchableWithoutFeedback
         {...props}
-        style={[evaStyle.control, styles.control, this.props.controlStyle]}
-        onPress={this.onPress}
-        onPressIn={this.onPressIn}
-        onPressOut={this.onPressOut}
+        style={[evaStyle.control, styles.control, props.controlStyle]}
+        onPress={onPress}
+        onPressIn={onPressIn}
+        onPressOut={onPressOut}
       >
         <FalsyFC
           style={evaStyle.icon}
-          component={this.props.accessoryLeft}
+          component={props.accessoryLeft}
         />
         <FalsyText
           style={evaStyle.text}
           numberOfLines={1}
           ellipsizeMode='tail'
-          component={this.getComponentTitle()}
+          component={getComponentTitle()}
         />
         <FalsyFC
           style={evaStyle.icon}
-          component={this.props.accessoryRight}
+          component={props.accessoryRight}
         />
       </TouchableWithoutFeedback>
     );
   };
 
-  public render(): React.ReactElement<ViewProps> {
-    const {
-      eva,
-      style,
-      testID,
-      backdropStyle,
-      controlStyle,
-      placement,
-      label,
-      accessoryLeft,
-      accessoryRight,
-      caption,
-      ...touchableProps
-    } = this.props;
-
-    const evaStyle = this.getComponentStyle(eva.style);
-
-    return (
-      <View
-        style={style}
-        testID={testID}
+  return (
+    <View
+      style={style}
+      testID={testID}
+    >
+      <FalsyText
+        style={[evaStyle.label, styles.label]}
+        component={label}
+      />
+      <Popover
+        style={[evaStyle.popover, styles.popover]}
+        backdropStyle={backdropStyle}
+        placement={placement}
+        visible={visible}
+        anchor={renderInputElement}
+        onBackdropPress={setPickerInvisible}
       >
-        <FalsyText
-          style={[evaStyle.label, styles.label]}
-          component={label}
-        />
-        <Popover
-          style={[evaStyle.popover, styles.popover]}
-          backdropStyle={backdropStyle}
-          placement={placement}
-          visible={this.state.visible}
-          anchor={() => this.renderInputElement(touchableProps, evaStyle)}
-          onBackdropPress={this.setPickerInvisible}
-        >
-          {this.renderCalendar()}
-        </Popover>
-        <FalsyText
-          style={[evaStyle.captionLabel, styles.captionLabel]}
-          component={caption}
-        />
-      </View>
-    );
-  }
+        {children}
+      </Popover>
+      <FalsyText
+        style={[evaStyle.captionLabel, styles.captionLabel]}
+        component={caption}
+      />
+    </View>
+  );
 }
 
+BaseDatepickerComponent.displayName = 'BaseDatepickerComponent';
+
+const Component = React.forwardRef(BaseDatepickerComponent);
+
+export {
+  Component as BaseDatepickerComponent,
+};
+
 const styles = StyleSheet.create({
   popover: {
     borderWidth: 0,
diff --git a/src/components/ui/datepicker/baseDatepicker.utils.ts b/src/components/ui/datepicker/baseDatepicker.utils.ts
new file mode 100644
index 000000000..e5c2c0f04
--- /dev/null
+++ b/src/components/ui/datepicker/baseDatepicker.utils.ts
@@ -0,0 +1,68 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+import { StyleType } from '../../theme';
+
+export const getComponentStyle = ({
+  textMarginHorizontal,
+  textFontFamily,
+  textFontSize,
+  textFontWeight,
+  textColor,
+  placeholderColor,
+  iconWidth,
+  iconHeight,
+  iconMarginHorizontal,
+  iconTintColor,
+  labelColor,
+  labelFontSize,
+  labelMarginBottom,
+  labelFontWeight,
+  labelFontFamily,
+  captionMarginTop,
+  captionColor,
+  captionFontSize,
+  captionFontWeight,
+  captionFontFamily,
+  popoverWidth,
+  ...controlParameters
+}: StyleType): StyleType => ({
+  control: controlParameters,
+  text: {
+    marginHorizontal: textMarginHorizontal,
+    fontFamily: textFontFamily,
+    fontSize: textFontSize,
+    fontWeight: textFontWeight,
+    color: textColor,
+  },
+  placeholder: {
+    marginHorizontal: textMarginHorizontal,
+    color: placeholderColor,
+  },
+  icon: {
+    width: iconWidth,
+    height: iconHeight,
+    marginHorizontal: iconMarginHorizontal,
+    tintColor: iconTintColor,
+  },
+  label: {
+    color: labelColor,
+    fontSize: labelFontSize,
+    fontFamily: labelFontFamily,
+    marginBottom: labelMarginBottom,
+    fontWeight: labelFontWeight,
+  },
+  captionLabel: {
+    fontSize: captionFontSize,
+    fontWeight: captionFontWeight,
+    fontFamily: captionFontFamily,
+    color: captionColor,
+  },
+  popover: {
+    width: popoverWidth,
+    marginBottom: captionMarginTop,
+  },
+});
diff --git a/src/components/ui/datepicker/datepicker.component.tsx b/src/components/ui/datepicker/datepicker.component.tsx
index 6d8c25799..2e8d128d9 100644
--- a/src/components/ui/datepicker/datepicker.component.tsx
+++ b/src/components/ui/datepicker/datepicker.component.tsx
@@ -4,17 +4,19 @@
  * Licensed under the MIT License. See License.txt in the project root for license information.
  */
 
+import { DateService, NativeDateService } from '@ui-kitten/components';
 import React from 'react';
 import { RenderProp } from '../../devsupport';
 import { styled } from '../../theme';
 import {
   BaseDatepickerComponent,
   BaseDatepickerProps,
+  BaseDatepickerRef,
 } from './baseDatepicker.component';
 import {
   Calendar,
-  CalendarElement,
   CalendarProps,
+  CalendarRef,
 } from '../calendar/calendar.component';
 import { TextProps } from '../text/text.component';
 
@@ -24,6 +26,10 @@ export interface DatepickerProps<D = Date> extends BaseDatepickerProps<D>, Calen
 
 export type DatepickerElement<D = Date> = React.ReactElement<DatepickerProps<D>>;
 
+export type DatepickerRef<D = Date> = CalendarRef<D> & BaseDatepickerRef & {
+  clear: () => void;
+};
+
 /**
  * Date picker provides a simple way to select a date within a picker displayed in modal.
  *
@@ -187,69 +193,84 @@ export type DatepickerElement<D = Date> = React.ReactElement<DatepickerProps<D>>
  * @overview-example DatepickerTheming
  * In most cases this is redundant, if [custom theme is configured](guides/branding).
  */
-@styled('Datepicker')
-export class Datepicker<D = Date> extends BaseDatepickerComponent<DatepickerProps<D>, D> {
-
-  static defaultProps: DatepickerProps = {
-    ...BaseDatepickerComponent.defaultProps,
-    autoDismiss: true,
-  };
+function Datepicker<D = Date>(
+  {
+    autoDismiss = true,
+    placeholder = 'dd/mm/yyyy',
+    ...props
+  }: DatepickerProps<D>,
+  ref: React.MutableRefObject<DatepickerRef<D>>
+): DatepickerElement<D> {
+  const baseDatepickerRef = React.useRef<BaseDatepickerRef>();
+  const dateService = props.dateService ?? new NativeDateService() as unknown as DateService<D>;
 
-  constructor(props: DatepickerProps<D>) {
-    super(props);
-    this.clear = this.clear.bind(this);
-  }
+  React.useImperativeHandle(ref, () => ({
+    ...ref.current,
+    ...baseDatepickerRef.current,
+    clear,
+  }));
 
-  private get calendarProps(): CalendarProps<D> {
-    return {
-      min: this.props.min,
-      max: this.props.max,
-      date: this.props.date,
-      initialVisibleDate: this.props.initialVisibleDate,
-      dateService: this.props.dateService,
-      boundingMonth: this.props.boundingMonth,
-      startView: this.props.startView,
-      filter: this.props.filter,
-      title: this.props.title,
-      onSelect: this.props.onSelect,
-      renderDay: this.props.renderDay,
-      renderMonth: this.props.renderMonth,
-      renderYear: this.props.renderYear,
-      renderFooter: this.props.renderFooter,
-      renderArrowRight: this.props.renderArrowRight,
-      renderArrowLeft: this.props.renderArrowLeft,
-      onVisibleDateChange: this.props.onVisibleDateChange,
-    };
-  }
+  const calendarProps: CalendarProps<D> = ({
+    dateService,
+    min: props.min,
+    max: props.max,
+    date: props.date,
+    initialVisibleDate: props.initialVisibleDate,
+    boundingMonth: props.boundingMonth,
+    startView: props.startView,
+    filter: props.filter,
+    title: props.title,
+    onSelect: props.onSelect,
+    renderDay: props.renderDay,
+    renderMonth: props.renderMonth,
+    renderYear: props.renderYear,
+    renderFooter: props.renderFooter,
+    renderArrowRight: props.renderArrowRight,
+    renderArrowLeft: props.renderArrowLeft,
+    onVisibleDateChange: props.onVisibleDateChange,
+  });
 
-  public clear = (): void => {
-    if (this.props.onSelect) {
-      this.props.onSelect(null);
+  const clear = (): void => {
+    if (props.onSelect) {
+      props.onSelect(null);
     }
   };
 
   // BaseDatepickerComponent
 
-  protected getComponentTitle(): RenderProp<TextProps> | React.ReactText {
-    if (this.props.date) {
-      return this.props.dateService.format(this.props.date, null);
+  const getComponentTitle = (): RenderProp<TextProps> | string | number => {
+    if (props.date) {
+      return dateService.format(props.date, null);
     } else {
-      return this.props.placeholder;
+      return placeholder;
     }
-  }
+  };
 
-  protected onSelect = (date: D): void => {
-    this.props.onSelect?.(date);
-    this.props.autoDismiss && this.blur();
+  const onSelect = (date: D): void => {
+    props.onSelect?.(date);
+    autoDismiss && baseDatepickerRef?.current?.blur?.();
   };
 
-  protected renderCalendar(): CalendarElement<D> {
-    return (
+  return (
+    <BaseDatepickerComponent
+      {...props}
+      dateService={dateService}
+      placeholder={placeholder}
+      ref={baseDatepickerRef}
+      getComponentTitle={getComponentTitle}
+      clear={clear}
+    >
       <Calendar
-        {...this.calendarProps}
-        ref={this.calendarRef}
-        onSelect={this.onSelect}
+        {...calendarProps}
+        ref={ref}
+        onSelect={onSelect}
       />
-    );
-  }
+    </BaseDatepickerComponent>
+  );
 }
+
+const Component = styled('Datepicker')(React.forwardRef(Datepicker));
+
+export {
+  Component as Datepicker,
+};
diff --git a/src/components/ui/datepicker/datepicker.spec.tsx b/src/components/ui/datepicker/datepicker.spec.tsx
index d84535ab2..19239d386 100644
--- a/src/components/ui/datepicker/datepicker.spec.tsx
+++ b/src/components/ui/datepicker/datepicker.spec.tsx
@@ -11,6 +11,7 @@ import {
   View,
 } from 'react-native';
 import {
+  act,
   fireEvent,
   render,
   RenderAPI,
@@ -24,6 +25,7 @@ import { ApplicationProvider } from '../../theme';
 import {
   Datepicker,
   DatepickerProps,
+  DatepickerRef,
 } from './datepicker.component';
 import { Calendar } from '../calendar/calendar.component';
 import { CalendarViewModes } from '../calendar/type';
@@ -47,7 +49,10 @@ describe('@datepicker: component checks', () => {
     jest.clearAllMocks();
   });
 
-  const TestDatepicker = React.forwardRef((props: Partial<DatepickerProps>, ref: React.Ref<Datepicker>) => {
+  const TestDatepicker = React.forwardRef((
+    props: Partial<DatepickerProps>,
+    ref: React.Ref<DatepickerRef>,
+  ) => {
     const [date, setDate] = React.useState(props.date);
 
     const onSelect = (nextDate: Date): void => {
@@ -379,7 +384,7 @@ describe('@datepicker: component checks', () => {
   });
 
   it('should show calendar by calling `focus` with ref', async () => {
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     const component = render(
       <TestDatepicker ref={componentRef} />,
@@ -392,7 +397,7 @@ describe('@datepicker: component checks', () => {
   });
 
   it('should hide calendar by calling `blur` with ref', async () => {
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     const component = render(
       <TestDatepicker ref={componentRef} />,
@@ -408,7 +413,7 @@ describe('@datepicker: component checks', () => {
   });
 
   it('should return false if calendar not visible by calling `isFocused` with ref', async () => {
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     render(
       <TestDatepicker ref={componentRef} />,
@@ -418,7 +423,7 @@ describe('@datepicker: component checks', () => {
   });
 
   it('should return true if calendar visible by calling `isFocused` with ref', async () => {
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     render(
       <TestDatepicker ref={componentRef} />,
@@ -431,7 +436,7 @@ describe('@datepicker: component checks', () => {
   });
 
   it('should call onSelect with null when calling `clear` with ref', async () => {
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
     const onSelect = jest.fn();
 
     render(
@@ -479,7 +484,7 @@ describe('@datepicker: component checks', () => {
 
   it('should show the selected date on load provided by date prop', () => {
     const date = new Date(2021, 2, 1);
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     render(
       <TestDatepicker
@@ -490,15 +495,14 @@ describe('@datepicker: component checks', () => {
 
     componentRef.current.focus();
 
-    // @ts-ignore: private calendarRef
-    const calendarState = componentRef.current.calendarRef.current.state;
+    const calendarState = componentRef.current.state;
     expect(calendarState.visibleDate.getFullYear()).toEqual(date.getFullYear());
     expect(calendarState.visibleDate.getMonth()).toEqual(date.getMonth());
   });
 
   it('should show the specific date on load provided by initialVisibleDate prop', () => {
     const initialDate = new Date(2021, 2, 1);
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     render(
       <TestDatepicker
@@ -510,14 +514,13 @@ describe('@datepicker: component checks', () => {
 
     componentRef.current.focus();
 
-    // @ts-ignore: private calendarRef
-    const visibleDate = componentRef.current.calendarRef.current.state.visibleDate;
+    const visibleDate = componentRef.current.state.visibleDate;
     expect(visibleDate.getFullYear()).toEqual(initialDate.getFullYear());
     expect(visibleDate.getMonth()).toEqual(initialDate.getMonth());
   });
 
-  it('should scroll to current month when scrollToToday called', () => {
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+  it('should scroll to current month when scrollToToday called', async () => {
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     render(
       <TestDatepicker
@@ -529,15 +532,14 @@ describe('@datepicker: component checks', () => {
     componentRef.current.focus();
     componentRef.current.scrollToToday();
 
-    // @ts-ignore: private calendarRef
-    const visibleDate = componentRef.current.calendarRef.current.state.visibleDate;
+    const visibleDate = componentRef.current.state.visibleDate;
     expect(visibleDate.getFullYear()).toEqual(today.getFullYear());
     expect(visibleDate.getMonth()).toEqual(today.getMonth());
   });
 
   it('should scroll to the specific date when scrollToDate called', () => {
     const dateToScroll = new Date(2021, 2, 1);
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     render(
       <TestDatepicker
@@ -549,14 +551,13 @@ describe('@datepicker: component checks', () => {
     componentRef.current.focus();
     componentRef.current.scrollToDate(dateToScroll);
 
-    // @ts-ignore: private calendarRef
-    const visibleDate = componentRef.current.calendarRef.current.state.visibleDate;
+    const visibleDate = componentRef.current.state.visibleDate;
     expect(visibleDate.getFullYear()).toEqual(dateToScroll.getFullYear());
     expect(visibleDate.getMonth()).toEqual(dateToScroll.getMonth());
   });
 
-  it('should render custom left arrow', () => {
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+  it('should render custom left arrow', async () => {
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     const onVisibleDateChange = jest.fn();
 
@@ -581,7 +582,9 @@ describe('@datepicker: component checks', () => {
       />
     );
 
-    componentRef.current?.focus();
+    await act(() => {
+      componentRef.current.focus();
+    });
 
     const leftArrow = component.queryByTestId('@arrow/left');
     fireEvent.press(leftArrow);
@@ -589,33 +592,33 @@ describe('@datepicker: component checks', () => {
     expect(onVisibleDateChange).toBeCalled();
   });
 
-  it('should render custom right arrow', () => {
-    const componentRef: React.RefObject<Datepicker> = React.createRef();
+  it('should render custom right arrow', async () => {
+    const componentRef: React.RefObject<DatepickerRef> = React.createRef();
 
     const onVisibleDateChange = jest.fn();
 
-    const renderArrow = (props: { onPress: () => void }): React.ReactElement => {
-      return (
-        <TouchableOpacity
-          testID='@arrow/right'
-          onPress={props.onPress}
-        >
-          <Text>
-            RIGHT
-          </Text>
-        </TouchableOpacity>
-      );
-    };
-
     const component = render(
       <TestDatepicker
         ref={componentRef}
-        renderArrowRight={renderArrow}
+        renderArrowRight={(props: { onPress: () => void }): React.ReactElement => {
+          return (
+            <TouchableOpacity
+              testID='@arrow/right'
+              onPress={props.onPress}
+            >
+              <Text>
+                RIGHT
+              </Text>
+            </TouchableOpacity>
+          );
+        }}
         onVisibleDateChange={onVisibleDateChange}
       />
     );
 
-    componentRef.current?.focus();
+    await act(() => {
+      componentRef.current.focus();
+    });
 
     const leftArrow = component.queryByTestId('@arrow/right');
     fireEvent.press(leftArrow);
diff --git a/src/components/ui/datepicker/rangeDatepicker.component.tsx b/src/components/ui/datepicker/rangeDatepicker.component.tsx
index 7699870f4..ce00c75b9 100644
--- a/src/components/ui/datepicker/rangeDatepicker.component.tsx
+++ b/src/components/ui/datepicker/rangeDatepicker.component.tsx
@@ -9,18 +9,24 @@ import { styled } from '../../theme';
 import {
   BaseDatepickerComponent,
   BaseDatepickerProps,
+  BaseDatepickerRef,
 } from './baseDatepicker.component';
 import {
   RangeCalendar,
   RangeCalendarElement,
   RangeCalendarProps,
+  RangeCalendarRef,
 } from '../calendar/rangeCalendar.component';
 import { RenderProp } from '@ui-kitten/components/devsupport';
-import { TextProps } from '@ui-kitten/components';
+import { DateService, NativeDateService, TextProps } from '@ui-kitten/components';
 
 export type RangeDatepickerProps<D = Date> = BaseDatepickerProps<D> & RangeCalendarProps<D>;
 export type RangeDatepickerElement<D = Date> = React.ReactElement<RangeDatepickerProps<D>>;
 
+export type RangeDatepickerRef<D = Date> = RangeCalendarRef<D> & BaseDatepickerRef & {
+  clear: () => void;
+};
+
 /**
  * Range date picker provides a simple way to select a date range within a picker displayed in modal.
  *
@@ -137,63 +143,75 @@ export type RangeDatepickerElement<D = Date> = React.ReactElement<RangeDatepicke
  * Ranged picker works with special range object - CalendarRange: `{ startDate: Date, endDate: Date }`.
  * For incomplete ranges, there is only a `startDate` property.
  */
-@styled('Datepicker')
-export class RangeDatepicker<D = Date> extends BaseDatepickerComponent<RangeDatepickerProps<D>, D> {
-
-  static styledComponentName = 'Datepicker';
+function RangeDatepicker<D = Date> (
+  {
+    placeholder = 'dd/mm/yyyy',
+    ...props
+  }: RangeDatepickerProps<D>,
+  ref: React.MutableRefObject<RangeDatepickerRef<D>>,
+): RangeCalendarElement {
+  const dateService = props.dateService ?? new NativeDateService() as unknown as DateService<D>;
 
-  constructor(props: RangeDatepickerProps<D>) {
-    super(props);
-    this.clear = this.clear.bind(this);
-  }
+  React.useImperativeHandle(ref, () => ({
+    ...ref.current,
+    clear,
+  }));
 
-  private get calendarProps(): RangeCalendarProps<D> {
-    return {
-      min: this.props.min,
-      max: this.props.max,
-      range: this.props.range,
-      initialVisibleDate: this.props.initialVisibleDate,
-      dateService: this.props.dateService,
-      boundingMonth: this.props.boundingMonth,
-      startView: this.props.startView,
-      filter: this.props.filter,
-      title: this.props.title,
-      onSelect: this.props.onSelect,
-      renderDay: this.props.renderDay,
-      renderMonth: this.props.renderMonth,
-      renderYear: this.props.renderYear,
-      renderFooter: this.props.renderFooter,
-      renderArrowRight: this.props.renderArrowRight,
-      renderArrowLeft: this.props.renderArrowLeft,
-      onVisibleDateChange: this.props.onVisibleDateChange,
-    };
-  }
+  const calendarProps: RangeCalendarProps<D> = ({
+    dateService,
+    min: props.min,
+    max: props.max,
+    range: props.range,
+    initialVisibleDate: props.initialVisibleDate,
+    boundingMonth: props.boundingMonth,
+    startView: props.startView,
+    filter: props.filter,
+    title: props.title,
+    onSelect: props.onSelect,
+    renderDay: props.renderDay,
+    renderMonth: props.renderMonth,
+    renderYear: props.renderYear,
+    renderFooter: props.renderFooter,
+    renderArrowRight: props.renderArrowRight,
+    renderArrowLeft: props.renderArrowLeft,
+    onVisibleDateChange: props.onVisibleDateChange,
+  });
 
-  public clear = (): void => {
-    this.props.onSelect?.({});
+  const clear = (): void => {
+    props.onSelect?.({});
   };
 
-  // BaseDatepickerComponent
-
-  protected getComponentTitle(): RenderProp<TextProps> | React.ReactText {
-    const { startDate, endDate } = this.props.range;
+  const getComponentTitle = (): RenderProp<TextProps> | string | number => {
+    const { startDate, endDate } = props.range;
 
     if (startDate || endDate) {
-      const start: string = startDate ? this.props.dateService.format(startDate, null) : '';
-      const end: string = endDate ? this.props.dateService.format(endDate, null) : '';
+      const start: string = startDate ? dateService.format(startDate, null) : '';
+      const end: string = endDate ? dateService.format(endDate, null) : '';
 
       return `${start} - ${end}`;
     } else {
-      return this.props.placeholder;
+      return placeholder;
     }
-  }
+  };
 
-  protected renderCalendar(): RangeCalendarElement<D> {
-    return (
+  return (
+    <BaseDatepickerComponent
+      {...props}
+      placeholder={placeholder}
+      ref={ref}
+      getComponentTitle={getComponentTitle}
+      clear={clear}
+    >
       <RangeCalendar
-        ref={this.calendarRef}
-        {...this.calendarProps}
+        {...calendarProps}
+        ref={ref}
       />
-    );
-  }
+    </BaseDatepickerComponent>
+  );
 }
+
+const Component = styled('Datepicker')(React.forwardRef(RangeDatepicker));
+
+export {
+  Component as RangeDatepicker,
+};
diff --git a/src/components/ui/datepicker/rangeDatepicker.spec.tsx b/src/components/ui/datepicker/rangeDatepicker.spec.tsx
index dbefd4f07..1886d083b 100644
--- a/src/components/ui/datepicker/rangeDatepicker.spec.tsx
+++ b/src/components/ui/datepicker/rangeDatepicker.spec.tsx
@@ -24,6 +24,7 @@ import { ApplicationProvider } from '../../theme';
 import {
   RangeDatepicker,
   RangeDatepickerProps,
+  RangeDatepickerRef,
 } from './rangeDatepicker.component';
 import { RangeCalendar } from '../calendar/rangeCalendar.component';
 import {
@@ -50,8 +51,10 @@ describe('@range-datepicker: component checks', () => {
     jest.clearAllMocks();
   });
 
-  const TestRangeDatepicker = React.forwardRef((props: Partial<RangeDatepickerProps>,
-    ref: React.Ref<RangeDatepicker>) => {
+  const TestRangeDatepicker = React.forwardRef((
+    props: Partial<RangeDatepickerProps>,
+    ref: React.Ref<RangeDatepickerRef>,
+  ) => {
     const [range, setRange] = React.useState(props.range || {});
 
     const onSelect = (nextRange: CalendarRange<Date>): void => {
@@ -127,7 +130,7 @@ describe('@range-datepicker: component checks', () => {
     expect(component.queryByText('I love Babel')).toBeTruthy();
   });
 
-  it('should render label as pure JSX component', async () => {
+  it('should render label as pure JSX component', () => {
     const component = render(
       <TestRangeDatepicker label={(
         <Text>
@@ -372,7 +375,7 @@ describe('@range-datepicker: component checks', () => {
   });
 
   it('should show calendar by calling `focus` with ref', async () => {
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
     const component = render(
       <TestRangeDatepicker ref={componentRef} />,
     );
@@ -384,7 +387,7 @@ describe('@range-datepicker: component checks', () => {
   });
 
   it('should hide calendar by calling `blur` with ref', async () => {
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
     const component = render(
       <TestRangeDatepicker ref={componentRef} />,
     );
@@ -399,7 +402,7 @@ describe('@range-datepicker: component checks', () => {
   });
 
   it('should return false if calendar not visible by calling `isFocused` with ref', async () => {
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
     render(
       <TestRangeDatepicker ref={componentRef} />,
     );
@@ -408,7 +411,7 @@ describe('@range-datepicker: component checks', () => {
   });
 
   it('should return true if calendar visible by calling `isFocused` with ref', async () => {
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
     render(
       <TestRangeDatepicker ref={componentRef} />,
     );
@@ -420,7 +423,7 @@ describe('@range-datepicker: component checks', () => {
   });
 
   it('should call onSelect with empty object when calling `clear` with ref', async () => {
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
     const onSelect = jest.fn();
 
     render(
@@ -468,7 +471,7 @@ describe('@range-datepicker: component checks', () => {
 
   it('should show startDate of the selected range on load provided by range prop', () => {
     const date = new Date(2021, 2, 1);
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
 
     render(
       <TestRangeDatepicker
@@ -482,15 +485,14 @@ describe('@range-datepicker: component checks', () => {
 
     componentRef.current.focus();
 
-    // @ts-ignore: private calendarRef
-    const calendarState = componentRef.current.calendarRef.current.state;
+    const calendarState = componentRef.current.state;
     expect(calendarState.visibleDate.getFullYear()).toEqual(date.getFullYear());
     expect(calendarState.visibleDate.getMonth()).toEqual(date.getMonth());
   });
 
   it('should show the specific date on load provided by initialVisibleDate prop', () => {
     const initialDate = new Date(2021, 2, 1);
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
 
     render(
       <TestRangeDatepicker
@@ -501,14 +503,13 @@ describe('@range-datepicker: component checks', () => {
 
     componentRef.current.focus();
 
-    // @ts-ignore: private calendarRef
-    const visibleDate = componentRef.current.calendarRef.current.state.visibleDate;
+    const visibleDate = componentRef.current.state.visibleDate;
     expect(visibleDate.getFullYear()).toEqual(initialDate.getFullYear());
     expect(visibleDate.getMonth()).toEqual(initialDate.getMonth());
   });
 
   it('should scroll to current month when scrollToToday called', () => {
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
 
     render(
       <TestRangeDatepicker
@@ -521,14 +522,14 @@ describe('@range-datepicker: component checks', () => {
     componentRef.current.scrollToToday();
 
     // @ts-ignore: private calendarRef
-    const visibleDate = componentRef.current.calendarRef.current.state.visibleDate;
+    const visibleDate = componentRef.current.state.visibleDate;
     expect(visibleDate.getFullYear()).toEqual(today.getFullYear());
     expect(visibleDate.getMonth()).toEqual(today.getMonth());
   });
 
   it('should scroll to the specific date when scrollToDate called', () => {
     const dateToScroll = new Date(2020, 1, 1);
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
 
     render(
       <TestRangeDatepicker
@@ -540,14 +541,13 @@ describe('@range-datepicker: component checks', () => {
     componentRef.current.focus();
     componentRef.current.scrollToDate(dateToScroll);
 
-    // @ts-ignore: private calendarRef
-    const visibleDate = componentRef.current.calendarRef.current.state.visibleDate;
+    const visibleDate = componentRef.current.state.visibleDate;
     expect(visibleDate.getFullYear()).toEqual(dateToScroll.getFullYear());
     expect(visibleDate.getMonth()).toEqual(dateToScroll.getMonth());
   });
 
   it('should render custom left arrow', () => {
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
 
     const onVisibleDateChange = jest.fn();
 
@@ -572,7 +572,7 @@ describe('@range-datepicker: component checks', () => {
       />
     );
 
-    componentRef.current?.focus();
+    componentRef.current.focus();
 
     const leftArrow = component.queryByTestId('@arrow/left');
     fireEvent.press(leftArrow);
@@ -581,7 +581,7 @@ describe('@range-datepicker: component checks', () => {
   });
 
   it('should render custom right arrow', () => {
-    const componentRef: React.RefObject<RangeDatepicker> = React.createRef();
+    const componentRef: React.RefObject<RangeDatepickerRef> = React.createRef();
 
     const onVisibleDateChange = jest.fn();
 
@@ -606,7 +606,7 @@ describe('@range-datepicker: component checks', () => {
       />
     );
 
-    componentRef.current?.focus();
+    componentRef.current.focus();
 
     const leftArrow = component.queryByTestId('@arrow/right');
     fireEvent.press(leftArrow);
diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts
index a95daaedb..f856e3b0c 100644
--- a/src/components/ui/index.ts
+++ b/src/components/ui/index.ts
@@ -38,6 +38,7 @@ export {
   Calendar,
   CalendarElement,
   CalendarProps,
+  CalendarRef,
 } from './calendar/calendar.component';
 export {
   Card,
@@ -48,6 +49,7 @@ export {
   RangeCalendar,
   RangeCalendarProps,
   RangeCalendarElement,
+  RangeCalendarRef,
 } from './calendar/rangeCalendar.component';
 export {
   CalendarRange,
@@ -64,11 +66,13 @@ export {
   Datepicker,
   DatepickerProps,
   DatepickerElement,
+  DatepickerRef,
 } from './datepicker/datepicker.component';
 export {
   RangeDatepicker,
   RangeDatepickerProps,
   RangeDatepickerElement,
+  RangeDatepickerRef,
 } from './datepicker/rangeDatepicker.component';
 export {
   Drawer,
diff --git a/src/showcases/components/calendar/calendarInitialVisibleDate.component.tsx b/src/showcases/components/calendar/calendarInitialVisibleDate.component.tsx
index 264c3aae5..e2e228a19 100644
--- a/src/showcases/components/calendar/calendarInitialVisibleDate.component.tsx
+++ b/src/showcases/components/calendar/calendarInitialVisibleDate.component.tsx
@@ -1,6 +1,6 @@
 import React from 'react';
 import { StyleSheet, View } from 'react-native';
-import { Button, Calendar, Layout, Text } from '@ui-kitten/components';
+import { Button, Calendar, CalendarRef, Layout, Text } from '@ui-kitten/components';
 
 const now = new Date();
 const date = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate());
@@ -9,7 +9,7 @@ const initialVisibleDate = new Date(now.getFullYear(), now.getMonth() + 3, now.g
 export const CalendarInitialVisibleDateShowcase = (): React.ReactElement => {
   const [selectedDate, setSelectedDate] = React.useState(date);
 
-  const componentRef = React.createRef<Calendar>();
+  const componentRef = React.useRef<CalendarRef>();
 
   const scrollToSelected = (): void => {
     if (componentRef.current) {
diff --git a/src/showcases/components/datepicker/datepickerInitialVisibleDate.component.tsx b/src/showcases/components/datepicker/datepickerInitialVisibleDate.component.tsx
index 627570d5e..dc915ce6b 100644
--- a/src/showcases/components/datepicker/datepickerInitialVisibleDate.component.tsx
+++ b/src/showcases/components/datepicker/datepickerInitialVisibleDate.component.tsx
@@ -1,6 +1,6 @@
 import React from 'react';
 import { StyleSheet, View } from 'react-native';
-import { Button, Datepicker, Layout, Text } from '@ui-kitten/components';
+import { Button, Datepicker, DatepickerRef, Layout, Text } from '@ui-kitten/components';
 
 const now = new Date();
 const date = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate());
@@ -10,7 +10,7 @@ export const DatepickerInitialVisibleDateShowcase = (): React.ReactElement => {
   const [selectedDate, setSelectedDate] = React.useState(date);
   const [initialVisibleDate, setInitialVisibleDate] = React.useState(initialDate);
 
-  const componentRef = React.createRef<Datepicker>();
+  const componentRef = React.useRef<DatepickerRef>();
 
   const scrollToSelected = (): void => {
     if (componentRef.current) {