diff --git a/src/components/AddPlaidBankAccount.js b/src/components/AddPlaidBankAccount.js
index ff97c9be24a6..d50fad0bd2f0 100644
--- a/src/components/AddPlaidBankAccount.js
+++ b/src/components/AddPlaidBankAccount.js
@@ -1,5 +1,5 @@
 import _ from 'underscore';
-import React from 'react';
+import React, {useEffect, useRef, useCallback} from 'react';
 import {ActivityIndicator, View} from 'react-native';
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
@@ -10,17 +10,16 @@ import * as BankAccounts from '../libs/actions/BankAccounts';
 import ONYXKEYS from '../ONYXKEYS';
 import styles from '../styles/styles';
 import themeColors from '../styles/themes/default';
-import compose from '../libs/compose';
-import withLocalize, {withLocalizePropTypes} from './withLocalize';
 import Picker from './Picker';
 import {plaidDataPropTypes} from '../pages/ReimbursementAccount/plaidDataPropTypes';
 import Text from './Text';
 import getBankIcon from './Icon/BankIcons';
 import Icon from './Icon';
 import FullPageOfflineBlockingView from './BlockingViews/FullPageOfflineBlockingView';
-import {withNetwork} from './OnyxProvider';
 import CONST from '../CONST';
 import KeyboardShortcut from '../libs/KeyboardShortcut';
+import useLocalize from '../hooks/useLocalize';
+import useNetwork from '../hooks/useNetwork';
 
 const propTypes = {
     /** Contains plaid data */
@@ -52,8 +51,6 @@ const propTypes = {
 
     /** Are we adding a withdrawal account? */
     allowDebit: PropTypes.bool,
-
-    ...withLocalizePropTypes,
 };
 
 const defaultProps = {
@@ -68,172 +65,163 @@ const defaultProps = {
     bankAccountID: 0,
 };
 
-class AddPlaidBankAccount extends React.Component {
-    constructor(props) {
-        super(props);
-
-        this.getPlaidLinkToken = this.getPlaidLinkToken.bind(this);
-        this.subscribedKeyboardShortcuts = [];
-    }
-
-    componentDidMount() {
-        this.subscribeToNavigationShortcuts();
-
-        // If we're coming from Plaid OAuth flow then we need to reuse the existing plaidLinkToken
-        if (this.isAuthenticatedWithPlaid()) {
-            return;
-        }
-
-        BankAccounts.openPlaidBankLogin(this.props.allowDebit, this.props.bankAccountID);
-    }
-
-    componentDidUpdate(prevProps) {
-        if (!prevProps.network.isOffline || this.props.network.isOffline || this.isAuthenticatedWithPlaid()) {
-            return;
-        }
-
-        // If we are coming back from offline and we haven't authenticated with Plaid yet, we need to re-run our call to kick off Plaid
-        BankAccounts.openPlaidBankLogin(this.props.allowDebit, this.props.bankAccountID);
-    }
+function AddPlaidBankAccount({plaidData, selectedPlaidAccountID, plaidLinkToken, onExitPlaid, onSelect, text, receivedRedirectURI, plaidLinkOAuthToken, bankAccountID, allowDebit}) {
+    const subscribedKeyboardShortcuts = useRef([]);
+    const previousNetworkState = useRef();
 
-    componentWillUnmount() {
-        this.unsubscribeToNavigationShortcuts();
-    }
+    const {translate} = useLocalize();
+    const {isOffline} = useNetwork();
 
     /**
      * @returns {String}
      */
-    getPlaidLinkToken() {
-        if (this.props.plaidLinkToken) {
-            return this.props.plaidLinkToken;
+    const getPlaidLinkToken = () => {
+        if (plaidLinkToken) {
+            return plaidLinkToken;
         }
 
-        if (this.props.receivedRedirectURI && this.props.plaidLinkOAuthToken) {
-            return this.props.plaidLinkOAuthToken;
+        if (receivedRedirectURI && plaidLinkOAuthToken) {
+            return plaidLinkOAuthToken;
         }
-    }
+    };
 
     /**
      * @returns {Boolean}
+     * I'm using useCallback so the useEffect which uses this function doesn't run on every render.
      */
-    isAuthenticatedWithPlaid() {
-        return (
-            (this.props.receivedRedirectURI && this.props.plaidLinkOAuthToken) ||
-            !_.isEmpty(lodashGet(this.props.plaidData, 'bankAccounts')) ||
-            !_.isEmpty(lodashGet(this.props.plaidData, 'errors'))
-        );
-    }
+    const isAuthenticatedWithPlaid = useCallback(
+        () => (receivedRedirectURI && plaidLinkOAuthToken) || !_.isEmpty(lodashGet(plaidData, 'bankAccounts')) || !_.isEmpty(lodashGet(plaidData, 'errors')),
+        [plaidData, plaidLinkOAuthToken, receivedRedirectURI],
+    );
 
     /**
      * Blocks the keyboard shortcuts that can navigate
      */
-    subscribeToNavigationShortcuts() {
+    const subscribeToNavigationShortcuts = () => {
         // find and block the shortcuts
         const shortcutsToBlock = _.filter(CONST.KEYBOARD_SHORTCUTS, (x) => x.type === CONST.KEYBOARD_SHORTCUTS_TYPES.NAVIGATION_SHORTCUT);
-        this.subscribedKeyboardShortcuts = _.map(shortcutsToBlock, (shortcut) =>
+        subscribedKeyboardShortcuts.current = _.map(shortcutsToBlock, (shortcut) =>
             KeyboardShortcut.subscribe(
                 shortcut.shortcutKey,
                 () => {}, // do nothing
                 shortcut.descriptionKey,
                 shortcut.modifiers,
                 false,
-                () => lodashGet(this.props.plaidData, 'bankAccounts', []).length > 0, // start bubbling when there are bank accounts
+                () => lodashGet(plaidData, 'bankAccounts', []).length > 0, // start bubbling when there are bank accounts
             ),
         );
-    }
+    };
 
     /**
      * Unblocks the keyboard shortcuts that can navigate
      */
-    unsubscribeToNavigationShortcuts() {
-        _.each(this.subscribedKeyboardShortcuts, (unsubscribe) => unsubscribe());
-        this.subscribedKeyboardShortcuts = [];
-    }
+    const unsubscribeToNavigationShortcuts = () => {
+        _.each(subscribedKeyboardShortcuts.current, (unsubscribe) => unsubscribe());
+        subscribedKeyboardShortcuts.current = [];
+    };
 
-    render() {
-        const plaidBankAccounts = lodashGet(this.props.plaidData, 'bankAccounts') || [];
-        const token = this.getPlaidLinkToken();
-        const options = _.map(plaidBankAccounts, (account) => ({
-            value: account.plaidAccountID,
-            label: `${account.addressName} ${account.mask}`,
-        }));
-        const {icon, iconSize} = getBankIcon();
-        const plaidErrors = lodashGet(this.props.plaidData, 'errors');
-        const plaidDataErrorMessage = !_.isEmpty(plaidErrors) ? _.chain(plaidErrors).values().first().value() : '';
-        const bankName = lodashGet(this.props.plaidData, 'bankName');
-
-        // Plaid Link view
-        if (!plaidBankAccounts.length) {
-            return (
-                <FullPageOfflineBlockingView>
-                    {lodashGet(this.props.plaidData, 'isLoading') && (
-                        <View style={[styles.flex1, styles.alignItemsCenter, styles.justifyContentCenter]}>
-                            <ActivityIndicator
-                                color={themeColors.spinner}
-                                size="large"
-                            />
-                        </View>
-                    )}
-                    {Boolean(plaidDataErrorMessage) && <Text style={[styles.formError, styles.mh5]}>{plaidDataErrorMessage}</Text>}
-                    {Boolean(token) && !bankName && (
-                        <PlaidLink
-                            token={token}
-                            onSuccess={({publicToken, metadata}) => {
-                                Log.info('[PlaidLink] Success!');
-                                BankAccounts.openPlaidBankAccountSelector(publicToken, metadata.institution.name, this.props.allowDebit, this.props.bankAccountID);
-                            }}
-                            onError={(error) => {
-                                Log.hmmm('[PlaidLink] Error: ', error.message);
-                            }}
-                            // User prematurely exited the Plaid flow
-                            // eslint-disable-next-line react/jsx-props-no-multi-spaces
-                            onExit={this.props.onExitPlaid}
-                            receivedRedirectURI={this.props.receivedRedirectURI}
-                        />
-                    )}
-                </FullPageOfflineBlockingView>
-            );
+    useEffect(() => {
+        subscribeToNavigationShortcuts();
+
+        // If we're coming from Plaid OAuth flow then we need to reuse the existing plaidLinkToken
+        if (isAuthenticatedWithPlaid()) {
+            return unsubscribeToNavigationShortcuts;
         }
+        BankAccounts.openPlaidBankLogin(allowDebit, bankAccountID);
+        return unsubscribeToNavigationShortcuts;
 
-        // Plaid bank accounts view
+        // disabling this rule, as we want this to run only on the first render
+        // eslint-disable-next-line react-hooks/exhaustive-deps
+    }, []);
+
+    useEffect(() => {
+        // If we are coming back from offline and we haven't authenticated with Plaid yet, we need to re-run our call to kick off Plaid
+        // previousNetworkState.current also makes sure that this doesn't run on the first render.
+        if (previousNetworkState.current && !isOffline && !isAuthenticatedWithPlaid()) {
+            BankAccounts.openPlaidBankLogin(allowDebit, bankAccountID);
+        }
+        previousNetworkState.current = isOffline;
+    }, [allowDebit, bankAccountID, isAuthenticatedWithPlaid, isOffline]);
+
+    const plaidBankAccounts = lodashGet(plaidData, 'bankAccounts') || [];
+    const token = getPlaidLinkToken();
+    const options = _.map(plaidBankAccounts, (account) => ({
+        value: account.plaidAccountID,
+        label: `${account.addressName} ${account.mask}`,
+    }));
+    const {icon, iconSize} = getBankIcon();
+    const plaidErrors = lodashGet(plaidData, 'errors');
+    const plaidDataErrorMessage = !_.isEmpty(plaidErrors) ? _.chain(plaidErrors).values().first().value() : '';
+    const bankName = lodashGet(plaidData, 'bankName');
+
+    // Plaid Link view
+    if (!plaidBankAccounts.length) {
         return (
             <FullPageOfflineBlockingView>
-                {!_.isEmpty(this.props.text) && <Text style={[styles.mb5]}>{this.props.text}</Text>}
-                <View style={[styles.flexRow, styles.alignItemsCenter, styles.mb5]}>
-                    <Icon
-                        src={icon}
-                        height={iconSize}
-                        width={iconSize}
-                    />
-                    <Text style={[styles.ml3, styles.textStrong]}>{bankName}</Text>
-                </View>
-                <View style={[styles.mb5]}>
-                    <Picker
-                        label={this.props.translate('addPersonalBankAccountPage.chooseAccountLabel')}
-                        onInputChange={this.props.onSelect}
-                        items={options}
-                        placeholder={{
-                            value: '',
-                            label: this.props.translate('bankAccount.chooseAnAccount'),
+                {lodashGet(plaidData, 'isLoading') && (
+                    <View style={[styles.flex1, styles.alignItemsCenter, styles.justifyContentCenter]}>
+                        <ActivityIndicator
+                            color={themeColors.spinner}
+                            size="large"
+                        />
+                    </View>
+                )}
+                {Boolean(plaidDataErrorMessage) && <Text style={[styles.formError, styles.mh5]}>{plaidDataErrorMessage}</Text>}
+                {Boolean(token) && !bankName && (
+                    <PlaidLink
+                        token={token}
+                        onSuccess={({publicToken, metadata}) => {
+                            Log.info('[PlaidLink] Success!');
+                            BankAccounts.openPlaidBankAccountSelector(publicToken, metadata.institution.name, allowDebit, bankAccountID);
+                        }}
+                        onError={(error) => {
+                            Log.hmmm('[PlaidLink] Error: ', error.message);
                         }}
-                        value={this.props.selectedPlaidAccountID}
+                        // User prematurely exited the Plaid flow
+                        // eslint-disable-next-line react/jsx-props-no-multi-spaces
+                        onExit={onExitPlaid}
+                        receivedRedirectURI={receivedRedirectURI}
                     />
-                </View>
+                )}
             </FullPageOfflineBlockingView>
         );
     }
+
+    // Plaid bank accounts view
+    return (
+        <FullPageOfflineBlockingView>
+            {!_.isEmpty(text) && <Text style={[styles.mb5]}>{text}</Text>}
+            <View style={[styles.flexRow, styles.alignItemsCenter, styles.mb5]}>
+                <Icon
+                    src={icon}
+                    height={iconSize}
+                    width={iconSize}
+                />
+                <Text style={[styles.ml3, styles.textStrong]}>{bankName}</Text>
+            </View>
+            <View style={[styles.mb5]}>
+                <Picker
+                    label={translate('addPersonalBankAccountPage.chooseAccountLabel')}
+                    onInputChange={onSelect}
+                    items={options}
+                    placeholder={{
+                        value: '',
+                        label: translate('bankAccount.chooseAnAccount'),
+                    }}
+                    value={selectedPlaidAccountID}
+                />
+            </View>
+        </FullPageOfflineBlockingView>
+    );
 }
 
 AddPlaidBankAccount.propTypes = propTypes;
 AddPlaidBankAccount.defaultProps = defaultProps;
-
-export default compose(
-    withLocalize,
-    withNetwork(),
-    withOnyx({
-        plaidLinkToken: {
-            key: ONYXKEYS.PLAID_LINK_TOKEN,
-            initWithStoredValues: false,
-        },
-    }),
-)(AddPlaidBankAccount);
+AddPlaidBankAccount.displayName = 'AddPlaidBankAccount';
+
+export default withOnyx({
+    plaidLinkToken: {
+        key: ONYXKEYS.PLAID_LINK_TOKEN,
+        initWithStoredValues: false,
+    },
+})(AddPlaidBankAccount);
