Skip to content

Commit d120f6a

Browse files
authored
Merge pull request #17400 from Expensify/marcaaron-useOnNetworkReconnect
`useOnNetworkReconnect()`
2 parents 86dc736 + 05d79db commit d120f6a

File tree

5 files changed

+37
-41
lines changed

5 files changed

+37
-41
lines changed

src/components/Avatar.js

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useEffect, useRef, useState} from 'react';
1+
import React, {useState} from 'react';
22
import {View} from 'react-native';
33
import PropTypes from 'prop-types';
44
import _ from 'underscore';
@@ -9,10 +9,9 @@ import CONST from '../CONST';
99
import * as StyleUtils from '../styles/StyleUtils';
1010
import * as Expensicons from './Icon/Expensicons';
1111
import Image from './Image';
12-
import {withNetwork} from './OnyxProvider';
13-
import networkPropTypes from './networkPropTypes';
1412
import styles from '../styles/styles';
1513
import * as ReportUtils from '../libs/ReportUtils';
14+
import useOnNetworkReconnect from './hooks/useOnNetworkReconnect';
1615

1716
const propTypes = {
1817
/** Source for the avatar. Can be a URL or an icon. */
@@ -44,9 +43,6 @@ const propTypes = {
4443

4544
/** Owner of the avatar, typically a login email or workspace name */
4645
name: PropTypes.string,
47-
48-
/** Props to detect online status */
49-
network: networkPropTypes.isRequired,
5046
};
5147

5248
const defaultProps = {
@@ -62,23 +58,8 @@ const defaultProps = {
6258

6359
function Avatar(props) {
6460
const [imageError, setImageError] = useState(false);
65-
const prevNetworkStatusRef = useRef(props.network.isOffline);
66-
67-
useEffect(() => {
68-
const isReconnecting = prevNetworkStatusRef.current && !props.network.isOffline;
69-
if (!imageError || !isReconnecting) {
70-
return;
71-
}
72-
setImageError(false);
73-
74-
// We have not added the imageError as the dependency because effect is concerned with `imageError` only when the network state changes from offline -> online
75-
// eslint-disable-next-line react-hooks/exhaustive-deps
76-
}, [props.network.isOffline]);
7761

78-
useEffect(() => {
79-
// Used to store previous network state to compare on next render
80-
prevNetworkStatusRef.current = props.network.isOffline;
81-
});
62+
useOnNetworkReconnect(() => setImageError(false));
8263

8364
if (!props.source) {
8465
return null;
@@ -128,4 +109,4 @@ function Avatar(props) {
128109
}
129110
Avatar.defaultProps = defaultProps;
130111
Avatar.propTypes = propTypes;
131-
export default withNetwork()(Avatar);
112+
export default Avatar;

src/components/OnyxProvider.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import ComposeProviders from './ComposeProviders';
66

77
// Set up any providers for individual keys. This should only be used in cases where many components will subscribe to
88
// the same key (e.g. FlatList renderItem components)
9-
const [withNetwork, NetworkProvider] = createOnyxContext(ONYXKEYS.NETWORK, {});
9+
const [withNetwork, NetworkProvider, NetworkContext] = createOnyxContext(ONYXKEYS.NETWORK, {});
1010
const [withPersonalDetails, PersonalDetailsProvider] = createOnyxContext(ONYXKEYS.PERSONAL_DETAILS);
1111
const [withCurrentDate, CurrentDateProvider] = createOnyxContext(ONYXKEYS.CURRENT_DATE);
1212
const [withReportActionsDrafts, ReportActionsDraftsProvider] = createOnyxContext(ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS);
@@ -45,4 +45,5 @@ export {
4545
withCurrentDate,
4646
withBlockedFromConcierge,
4747
withBetas,
48+
NetworkContext,
4849
};

src/components/createOnyxContext.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@ export default (onyxKeyName, defaultValue) => {
5151
return Consumer;
5252
};
5353

54-
return [withOnyxKey, ProviderWithOnyx];
54+
return [withOnyxKey, ProviderWithOnyx, Context];
5555
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {useRef, useContext, useEffect} from 'react';
2+
import {NetworkContext} from '../OnyxProvider';
3+
4+
/**
5+
* @param {Function} onNetworkReconnect
6+
*/
7+
export default function useOnNetworkReconnect(onNetworkReconnect) {
8+
const callback = useRef(onNetworkReconnect);
9+
callback.current = onNetworkReconnect;
10+
11+
const {isOffline} = useContext(NetworkContext);
12+
const prevOfflineStatusRef = useRef(isOffline);
13+
useEffect(() => {
14+
// If we were offline before and now we are not offline then we just reconnected
15+
const didReconnect = prevOfflineStatusRef.current && !isOffline;
16+
if (!didReconnect) {
17+
return;
18+
}
19+
20+
callback.current();
21+
}, [isOffline]);
22+
23+
useEffect(() => {
24+
// Used to store previous prop values to compare on next render
25+
prevOfflineStatusRef.current = isOffline;
26+
}, [isOffline]);
27+
}

src/pages/iou/MoneyRequestModal.js

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ import ScreenWrapper from '../../components/ScreenWrapper';
2323
import CONST from '../../CONST';
2424
import * as PersonalDetails from '../../libs/actions/PersonalDetails';
2525
import withCurrentUserPersonalDetails from '../../components/withCurrentUserPersonalDetails';
26-
import networkPropTypes from '../../components/networkPropTypes';
27-
import {withNetwork} from '../../components/OnyxProvider';
2826
import reportPropTypes from '../reportPropTypes';
2927
import * as ReportUtils from '../../libs/ReportUtils';
3028
import * as ReportScrollManager from '../../libs/ReportScrollManager';
29+
import useOnNetworkReconnect from '../../components/hooks/useOnNetworkReconnect';
3130
import * as DeviceCapabilities from '../../libs/DeviceCapabilities';
3231
import * as CurrencyUtils from '../../libs/CurrencyUtils';
3332

@@ -45,9 +44,6 @@ const propTypes = {
4544
// eslint-disable-next-line react/no-unused-prop-types
4645
report: reportPropTypes,
4746

48-
/** Information about the network */
49-
network: networkPropTypes.isRequired,
50-
5147
// Holds data related to request view state, rather than the underlying request data.
5248
iou: PropTypes.shape({
5349
/** Whether or not transaction creation has started */
@@ -113,7 +109,6 @@ const MoneyRequestModal = (props) => {
113109
: [Steps.MoneyRequestAmount, Steps.MoneyRequestParticipants, Steps.MoneyRequestConfirm]),
114110
[reportParticipants.length]);
115111
const prevCreatingIOUTransactionStatusRef = useRef(lodashGet(props.iou, 'creatingIOUTransaction'));
116-
const prevNetworkStatusRef = useRef(props.network.isOffline);
117112

118113
const [previousStepIndex, setPreviousStepIndex] = useState(-1);
119114
const [currentStepIndex, setCurrentStepIndex] = useState(0);
@@ -145,18 +140,11 @@ const MoneyRequestModal = (props) => {
145140
}
146141
}, [props.iou]);
147142

148-
useEffect(() => {
149-
if (props.network.isOffline || !prevNetworkStatusRef.current) {
150-
return;
151-
}
152-
153-
// User came back online, so let's refetch the currency details based on location
154-
PersonalDetails.openMoneyRequestModalPage();
155-
}, [props.network.isOffline]);
143+
// User came back online, so let's refetch the currency details based on location
144+
useOnNetworkReconnect(PersonalDetails.openMoneyRequestModalPage);
156145

157146
useEffect(() => {
158147
// Used to store previous prop values to compare on next render
159-
prevNetworkStatusRef.current = props.network.isOffline;
160148
prevCreatingIOUTransactionStatusRef.current = lodashGet(props.iou, 'creatingIOUTransaction');
161149
});
162150

@@ -453,7 +441,6 @@ MoneyRequestModal.defaultProps = defaultProps;
453441

454442
export default compose(
455443
withLocalize,
456-
withNetwork(),
457444
withCurrentUserPersonalDetails,
458445
withOnyx({
459446
report: {

0 commit comments

Comments
 (0)