diff --git a/src/pages/workspace/WorkspaceMembersPage.tsx b/src/pages/workspace/WorkspaceMembersPage.tsx index 7b77f6b60ede..9f210cb6d2ac 100644 --- a/src/pages/workspace/WorkspaceMembersPage.tsx +++ b/src/pages/workspace/WorkspaceMembersPage.tsx @@ -146,10 +146,14 @@ function WorkspaceMembersPage({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedEmployees, policy?.owner, session?.accountID]); + // useFocusEffect would make getWorkspaceMembers get called twice on fresh login because policyMember is a dependency of getWorkspaceMembers. useEffect(() => { + if (!isFocused) { + return; + } getWorkspaceMembers(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [isFocused]); useEffect(() => { validateSelection(); diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index c717c4a2f14e..77c8bf4f5a05 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -1,5 +1,6 @@ +import {useFocusEffect} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect} from 'react'; +import React, {useCallback} from 'react'; import {View} from 'react-native'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Illustrations from '@components/Icon/Illustrations'; @@ -175,16 +176,17 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro [isSmallScreenWidth, styles, renderItem, translate], ); - function fetchFeatures() { + const fetchFeatures = useCallback(() => { Policy.openPolicyMoreFeaturesPage(route.params.policyID); - } + }, [route.params.policyID]); useNetwork({onReconnect: fetchFeatures}); - useEffect(() => { - fetchFeatures(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useFocusEffect( + useCallback(() => { + fetchFeatures(); + }, [fetchFeatures]), + ); return ( diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index 244b9f85b79a..4889c1dbe350 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -1,6 +1,6 @@ -import {useIsFocused} from '@react-navigation/native'; +import {useFocusEffect, useIsFocused} from '@react-navigation/native'; import type {ReactNode} from 'react'; -import React, {useEffect, useMemo, useRef} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; @@ -135,9 +135,11 @@ function WorkspacePageWithSections({ firstRender.current = false; }, []); - useEffect(() => { - fetchData(policyID, shouldSkipVBBACall); - }, [policyID, shouldSkipVBBACall]); + useFocusEffect( + useCallback(() => { + fetchData(policyID, shouldSkipVBBACall); + }, [policyID, shouldSkipVBBACall]), + ); const shouldShow = useMemo(() => { // If the policy object doesn't exist or contains only error data, we shouldn't display it. diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index c5e79effe276..5b246caa6e07 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -1,5 +1,6 @@ +import {useFocusEffect} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useMemo, useRef, useState} from 'react'; import {ActivityIndicator, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; @@ -62,16 +63,17 @@ function WorkspaceCategoriesPage({policy, policyCategories, route}: WorkspaceCat const dropdownButtonRef = useRef(null); const [deleteCategoriesConfirmModalVisible, setDeleteCategoriesConfirmModalVisible] = useState(false); - function fetchCategories() { + const fetchCategories = useCallback(() => { Policy.openPolicyCategoriesPage(route.params.policyID); - } + }, [route.params.policyID]); const {isOffline} = useNetwork({onReconnect: fetchCategories}); - useEffect(() => { - fetchCategories(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useFocusEffect( + useCallback(() => { + fetchCategories(); + }, [fetchCategories]), + ); const categoryList = useMemo( () => diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx index a5356a8fd05a..faa766945452 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx @@ -1,5 +1,6 @@ +import {useFocusEffect} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useMemo, useRef, useState} from 'react'; import {ActivityIndicator, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; @@ -67,9 +68,9 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps) [allSelectableRates, selectedDistanceRates], ); - function fetchDistanceRates() { + const fetchDistanceRates = useCallback(() => { Policy.openPolicyDistanceRatesPage(policyID); - } + }, [policyID]); const dismissError = useCallback( (item: RateForList) => { @@ -85,10 +86,11 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps) const {isOffline} = useNetwork({onReconnect: fetchDistanceRates}); - useEffect(() => { - fetchDistanceRates(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useFocusEffect( + useCallback(() => { + fetchDistanceRates(); + }, [fetchDistanceRates]), + ); const distanceRatesList = useMemo( () => diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index 53376c05878f..56cf00582782 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -1,6 +1,7 @@ +import {useFocusEffect} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import lodashSortBy from 'lodash/sortBy'; -import React, {useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useMemo, useRef, useState} from 'react'; import {ActivityIndicator, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; @@ -69,16 +70,17 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { const dropdownButtonRef = useRef(null); const [deleteTagsConfirmModalVisible, setDeleteTagsConfirmModalVisible] = useState(false); - function fetchTags() { + const fetchTags = useCallback(() => { Policy.openPolicyTagsPage(route.params.policyID); - } + }, [route.params.policyID]); const {isOffline} = useNetwork({onReconnect: fetchTags}); - useEffect(() => { - fetchTags(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useFocusEffect( + useCallback(() => { + fetchTags(); + }, [fetchTags]), + ); const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTags), [policyTags]); const tagList = useMemo( () => diff --git a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx index 4f8782dcdf3f..8ce33ec783c0 100644 --- a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx +++ b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx @@ -1,5 +1,6 @@ +import {useFocusEffect} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import React, {useCallback, useMemo, useRef, useState} from 'react'; import {ActivityIndicator, View} from 'react-native'; import Button from '@components/Button'; import ButtonWithDropdownMenu from '@components/ButtonWithDropdownMenu'; @@ -52,16 +53,17 @@ function WorkspaceTaxesPage({ const foreignTaxDefault = policy?.taxRates?.foreignTaxDefault; const dropdownButtonRef = useRef(null); - const fetchTaxes = () => { + const fetchTaxes = useCallback(() => { openPolicyTaxesPage(policyID); - }; + }, [policyID]); const {isOffline} = useNetwork({onReconnect: fetchTaxes}); - useEffect(() => { - fetchTaxes(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useFocusEffect( + useCallback(() => { + fetchTaxes(); + }, [fetchTaxes]), + ); const textForDefault = useCallback( (taxID: string): string => { diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 466343ffa477..f810020fd733 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,5 +1,6 @@ +import {useFocusEffect} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useMemo, useState} from 'react'; +import React, {useCallback, useMemo, useState} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; @@ -62,9 +63,9 @@ function WorkspaceWorkflowsPage({policy, betas, route, session}: WorkspaceWorkfl const onPressAutoReportingFrequency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id ?? '')), [policy?.id]); - const fetchData = () => { + const fetchData = useCallback(() => { Policy.openPolicyWorkflowsPage(policy?.id ?? route.params.policyID); - }; + }, [policy?.id, route.params.policyID]); const confirmCurrencyChangeAndHideModal = useCallback(() => { if (!policy) { @@ -78,10 +79,11 @@ function WorkspaceWorkflowsPage({policy, betas, route, session}: WorkspaceWorkfl const {isOffline} = useNetwork({onReconnect: fetchData}); const isPolicyAdmin = PolicyUtils.isPolicyAdmin(policy); - useEffect(() => { - fetchData(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useFocusEffect( + useCallback(() => { + fetchData(); + }, [fetchData]), + ); const optionItems: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, addressName, bankName} = policy?.achAccount ?? {};