diff --git a/src/components/Avatar.js b/src/components/Avatar.js
index 687ed8d4f5c4..7aebb1d8fe68 100644
--- a/src/components/Avatar.js
+++ b/src/components/Avatar.js
@@ -1,4 +1,4 @@
-import React, {PureComponent} from 'react';
+import React, {useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import _ from 'underscore';
@@ -60,71 +60,72 @@ const defaultProps = {
name: '',
};
-class Avatar extends PureComponent {
- constructor(props) {
- super(props);
- this.state = {
- imageError: false,
- };
- }
+function Avatar(props) {
+ const [imageError, setImageError] = useState(false);
+ const prevNetworkStatusRef = useRef(props.network.isOffline);
- componentDidUpdate(prevProps) {
- const isReconnecting = prevProps.network.isOffline && !this.props.network.isOffline;
- if (!this.state.imageError || !isReconnecting) {
+ useEffect(() => {
+ const isReconnecting = prevNetworkStatusRef.current && !props.network.isOffline;
+ if (!imageError || !isReconnecting) {
return;
}
- this.setState({imageError: false});
- }
+ setImageError(false);
- render() {
- if (!this.props.source) {
- return null;
- }
+ // We have not added the imageError as the dependency because effect is concerned with `imageError` only when the network state changes from offline -> online
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [props.network.isOffline]);
- const isWorkspace = this.props.type === CONST.ICON_TYPE_WORKSPACE;
- const iconSize = StyleUtils.getAvatarSize(this.props.size);
-
- const imageStyle = [
- StyleUtils.getAvatarStyle(this.props.size),
- ...this.props.imageStyles,
- StyleUtils.getAvatarBorderRadius(this.props.size, this.props.type),
- ];
-
- const iconStyle = [
- StyleUtils.getAvatarStyle(this.props.size),
- styles.bgTransparent,
- ...this.props.imageStyles,
- ];
-
- const iconFillColor = isWorkspace ? StyleUtils.getDefaultWorspaceAvatarColor(this.props.name).fill : this.props.fill;
- const fallbackAvatar = isWorkspace ? ReportUtils.getDefaultWorkspaceAvatar(this.props.name) : this.props.fallbackIcon;
-
- return (
-
- {_.isFunction(this.props.source) || this.state.imageError
- ? (
-
-
-
- )
- : (
- this.setState({imageError: true})} />
- )}
-
- );
+ useEffect(() => {
+ // Used to store previous network state to compare on next render
+ prevNetworkStatusRef.current = props.network.isOffline;
+ });
+
+ if (!props.source) {
+ return null;
}
-}
+ const isWorkspace = props.type === CONST.ICON_TYPE_WORKSPACE;
+ const iconSize = StyleUtils.getAvatarSize(props.size);
+
+ const imageStyle = [
+ StyleUtils.getAvatarStyle(props.size),
+ ...props.imageStyles,
+ StyleUtils.getAvatarBorderRadius(props.size, props.type),
+ ];
+
+ const iconStyle = [
+ StyleUtils.getAvatarStyle(props.size),
+ styles.bgTransparent,
+ ...props.imageStyles,
+ ];
+
+ const iconFillColor = isWorkspace ? StyleUtils.getDefaultWorkspaceAvatarColor(props.name).fill : props.fill;
+ const fallbackAvatar = isWorkspace ? ReportUtils.getDefaultWorkspaceAvatar(props.name) : props.fallbackIcon;
+
+ return (
+
+ {_.isFunction(props.source) || imageError
+ ? (
+
+
+
+ )
+ : (
+ setImageError(true)} />
+ )}
+
+ );
+}
Avatar.defaultProps = defaultProps;
Avatar.propTypes = propTypes;
export default withNetwork()(Avatar);
diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js
index 335efcf2e423..ffd454539a26 100644
--- a/src/styles/StyleUtils.js
+++ b/src/styles/StyleUtils.js
@@ -116,7 +116,7 @@ function getAvatarBorderStyle(size, type) {
* @param {String} [workspaceName]
* @returns {Object}
*/
-function getDefaultWorspaceAvatarColor(workspaceName) {
+function getDefaultWorkspaceAvatarColor(workspaceName) {
const colorHash = ReportUtils.hashLogin(workspaceName.trim(), workspaceColorOptions.length);
return workspaceColorOptions[colorHash];
@@ -980,7 +980,7 @@ export {
getEmojiSuggestionItemStyle,
getEmojiSuggestionContainerStyle,
getColoredBackgroundStyle,
- getDefaultWorspaceAvatarColor,
+ getDefaultWorkspaceAvatarColor,
getAvatarBorderRadius,
getEmojiReactionBubbleStyle,
getEmojiReactionBubbleTextStyle,