diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js
index 2e02a794ed03..4af8fd161546 100644
--- a/src/pages/home/report/ReportActionsList.js
+++ b/src/pages/home/report/ReportActionsList.js
@@ -1,6 +1,6 @@
 import PropTypes from 'prop-types';
-import React from 'react';
-import {Animated} from 'react-native';
+import React, {useCallback, useEffect, useState} from 'react';
+import Animated, {useSharedValue, useAnimatedStyle, withTiming} from 'react-native-reanimated';
 import _ from 'underscore';
 import InvertedFlatList from '../../../components/InvertedFlatList';
 import withDrawerState, {withDrawerPropTypes} from '../../../components/withDrawerState';
@@ -17,7 +17,6 @@ import participantPropTypes from '../../../components/participantPropTypes';
 import * as ReportActionsUtils from '../../../libs/ReportActionsUtils';
 import reportActionPropTypes from './reportActionPropTypes';
 import CONST from '../../../CONST';
-import * as StyleUtils from '../../../styles/StyleUtils';
 import reportPropTypes from '../../reportPropTypes';
 import networkPropTypes from '../../../components/networkPropTypes';
 import withLocalize from '../../../components/withLocalize';
@@ -64,147 +63,132 @@ const defaultProps = {
     isLoadingMoreReportActions: false,
 };
 
-class ReportActionsList extends React.Component {
-    constructor(props) {
-        super(props);
-        this.renderItem = this.renderItem.bind(this);
-        this.keyExtractor = this.keyExtractor.bind(this);
-
-        this.state = {
-            fadeInAnimation: new Animated.Value(0),
-            skeletonViewHeight: 0,
-        };
-    }
-
-    componentDidMount() {
-        this.fadeIn();
-    }
-
-    fadeIn() {
-        Animated.timing(this.state.fadeInAnimation, {
-            toValue: 1,
-            duration: 100,
-            useNativeDriver: true,
-        }).start();
-    }
+/**
+ * Create a unique key for each action in the FlatList.
+ * We use the reportActionID that is a string representation of a random 64-bit int, which should be
+ * random enough to avoid collisions
+ * @param {Object} item
+ * @param {Object} item.action
+ * @return {String}
+ */
+function keyExtractor(item) {
+    return item.reportActionID;
+}
+
+const ReportActionsList = (props) => {
+    const opacity = useSharedValue(0);
+    const animatedStyles = useAnimatedStyle(() => ({
+        opacity: withTiming(opacity.value, {duration: 100}),
+    }));
+    useEffect(() => {
+        opacity.value = 1;
+    }, [opacity]);
+    const [skeletonViewHeight, setSkeletonViewHeight] = useState(0);
+
+    const windowHeight = props.windowHeight;
 
     /**
      * Calculates the ideal number of report actions to render in the first render, based on the screen height and on
      * the height of the smallest report action possible.
      * @return {Number}
      */
-    calculateInitialNumToRender() {
+    const calculateInitialNumToRender = useCallback(() => {
         const minimumReportActionHeight = styles.chatItem.paddingTop + styles.chatItem.paddingBottom
             + variables.fontSizeNormalHeight;
-        const availableHeight = this.props.windowHeight
+        const availableHeight = windowHeight
             - (CONST.CHAT_FOOTER_MIN_HEIGHT + variables.contentHeaderHeight);
         return Math.ceil(availableHeight / minimumReportActionHeight);
-    }
+    }, [windowHeight]);
 
-    /**
-     * Create a unique key for each action in the FlatList.
-     * We use the reportActionID that is a string representation of a random 64-bit int, which should be
-     * random enough to avoid collisions
-     * @param {Object} item
-     * @param {Object} item.action
-     * @return {String}
-     */
-    keyExtractor(item) {
-        return item.reportActionID;
-    }
+    const report = props.report;
+    const hasOutstandingIOU = props.report.hasOutstandingIOU;
+    const newMarkerReportActionID = props.newMarkerReportActionID;
+    const sortedReportActions = props.sortedReportActions;
+    const mostRecentIOUReportActionID = props.mostRecentIOUReportActionID;
 
     /**
-     * Do not move this or make it an anonymous function it is a method
-     * so it will not be recreated each time we render an item
-     *
-     * See: https://reactnative.dev/docs/optimizing-flatlist-configuration#avoid-anonymous-function-on-renderitem
-     *
      * @param {Object} args
      * @param {Number} args.index
-     *
      * @returns {React.Component}
      */
-    renderItem({
+    const renderItem = useCallback(({
         item: reportAction,
         index,
-    }) {
+    }) => {
         // When the new indicator should not be displayed we explicitly set it to null
-        const shouldDisplayNewMarker = reportAction.reportActionID === this.props.newMarkerReportActionID;
+        const shouldDisplayNewMarker = reportAction.reportActionID === newMarkerReportActionID;
         return (
             <ReportActionItem
-                report={this.props.report}
+                report={report}
                 action={reportAction}
-                displayAsGroup={ReportActionsUtils.isConsecutiveActionMadeByPreviousActor(this.props.sortedReportActions, index)}
+                displayAsGroup={ReportActionsUtils.isConsecutiveActionMadeByPreviousActor(sortedReportActions, index)}
                 shouldDisplayNewMarker={shouldDisplayNewMarker}
-                isMostRecentIOUReportAction={reportAction.reportActionID === this.props.mostRecentIOUReportActionID}
-                hasOutstandingIOU={this.props.report.hasOutstandingIOU}
+                isMostRecentIOUReportAction={reportAction.reportActionID === mostRecentIOUReportActionID}
+                hasOutstandingIOU={hasOutstandingIOU}
                 index={index}
             />
         );
-    }
-
-    render() {
-        // Native mobile does not render updates flatlist the changes even though component did update called.
-        // To notify there something changes we can use extraData prop to flatlist
-        const extraData = (!this.props.isDrawerOpen && this.props.isSmallScreenWidth) ? this.props.newMarkerReportActionID : undefined;
-        const shouldShowReportRecipientLocalTime = ReportUtils.canShowReportRecipientLocalTime(this.props.personalDetails, this.props.report);
-        return (
-            <Animated.View style={[StyleUtils.fade(this.state.fadeInAnimation), styles.flex1]}>
-                <InvertedFlatList
-                    accessibilityLabel={this.props.translate('sidebarScreen.listOfChatMessages')}
-                    ref={ReportScrollManager.flatListRef}
-                    data={this.props.sortedReportActions}
-                    renderItem={this.renderItem}
-                    contentContainerStyle={[
-                        styles.chatContentScrollView,
-                        shouldShowReportRecipientLocalTime && styles.pt0,
-                    ]}
-                    keyExtractor={this.keyExtractor}
-                    initialRowHeight={32}
-                    initialNumToRender={this.calculateInitialNumToRender()}
-                    onEndReached={this.props.loadMoreChats}
-                    onEndReachedThreshold={0.75}
-                    ListFooterComponent={() => {
-                        if (this.props.report.isLoadingMoreReportActions) {
-                            return (
-                                <ReportActionsSkeletonView
-                                    containerHeight={CONST.CHAT_SKELETON_VIEW.AVERAGE_ROW_HEIGHT * 3}
-                                />
-                            );
-                        }
-
-                        // Make sure the oldest report action loaded is not the first. This is so we do not show the
-                        // skeleton view above the created action in a newly generated optimistic chat or one with not
-                        // that many comments.
-                        const lastReportAction = _.last(this.props.sortedReportActions) || {};
-                        if (this.props.report.isLoadingReportActions && lastReportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED) {
-                            return (
-                                <ReportActionsSkeletonView
-                                    containerHeight={this.state.skeletonViewHeight}
-                                    animate={!this.props.network.isOffline}
-                                />
-                            );
-                        }
-
-                        return null;
-                    }}
-                    keyboardShouldPersistTaps="handled"
-                    onLayout={(event) => {
-                        this.setState({
-                            skeletonViewHeight: event.nativeEvent.layout.height,
-                        });
-                        this.props.onLayout(event);
-                    }}
-                    onScroll={this.props.onScroll}
-                    extraData={extraData}
-                />
-            </Animated.View>
-        );
-    }
-}
+    }, [report, hasOutstandingIOU, newMarkerReportActionID, sortedReportActions, mostRecentIOUReportActionID]);
+
+    // Native mobile does not render updates flatlist the changes even though component did update called.
+    // To notify there something changes we can use extraData prop to flatlist
+    const extraData = (!props.isDrawerOpen && props.isSmallScreenWidth) ? props.newMarkerReportActionID : undefined;
+    const shouldShowReportRecipientLocalTime = ReportUtils.canShowReportRecipientLocalTime(props.personalDetails, props.report);
+    return (
+        <Animated.View style={[animatedStyles, styles.flex1]}>
+            <InvertedFlatList
+                accessibilityLabel={props.translate('sidebarScreen.listOfChatMessages')}
+                ref={ReportScrollManager.flatListRef}
+                data={props.sortedReportActions}
+                renderItem={renderItem}
+                contentContainerStyle={[
+                    styles.chatContentScrollView,
+                    shouldShowReportRecipientLocalTime && styles.pt0,
+                ]}
+                keyExtractor={keyExtractor}
+                initialRowHeight={32}
+                initialNumToRender={calculateInitialNumToRender()}
+                onEndReached={props.loadMoreChats}
+                onEndReachedThreshold={0.75}
+                ListFooterComponent={() => {
+                    if (props.report.isLoadingMoreReportActions) {
+                        return (
+                            <ReportActionsSkeletonView
+                                containerHeight={CONST.CHAT_SKELETON_VIEW.AVERAGE_ROW_HEIGHT * 3}
+                            />
+                        );
+                    }
+
+                    // Make sure the oldest report action loaded is not the first. This is so we do not show the
+                    // skeleton view above the created action in a newly generated optimistic chat or one with not
+                    // that many comments.
+                    const lastReportAction = _.last(props.sortedReportActions) || {};
+                    if (props.report.isLoadingReportActions && lastReportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED) {
+                        return (
+                            <ReportActionsSkeletonView
+                                containerHeight={skeletonViewHeight}
+                                animate={!props.network.isOffline}
+                            />
+                        );
+                    }
+
+                    return null;
+                }}
+                keyboardShouldPersistTaps="handled"
+                onLayout={(event) => {
+                    setSkeletonViewHeight(event.nativeEvent.layout.height);
+                    props.onLayout(event);
+                }}
+                onScroll={props.onScroll}
+                extraData={extraData}
+            />
+        </Animated.View>
+    );
+};
 
 ReportActionsList.propTypes = propTypes;
 ReportActionsList.defaultProps = defaultProps;
+ReportActionsList.displayName = 'ReportActionsList';
 
 export default compose(
     withDrawerState,
diff --git a/src/setup/index.js b/src/setup/index.js
index 352417242ade..eae7036331c9 100644
--- a/src/setup/index.js
+++ b/src/setup/index.js
@@ -53,4 +53,11 @@ export default function () {
 
     // Perform any other platform-specific setup
     platformSetup();
+
+    // Workaround to a reanimated issue -> https://github.com/software-mansion/react-native-reanimated/issues/3355
+    // We can remove it as soon as we are on > reanimated 3.0.0+
+    if (process.browser) {
+        // eslint-disable-next-line no-underscore-dangle
+        window._frameTimestamp = null;
+    }
 }