From 406b8659343895a760cda4a4c98f77bf6ca0789f Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Mon, 10 Apr 2023 12:11:00 +0530 Subject: [PATCH 1/3] used useEffect --- src/components/Avatar.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 687ed8d4f5c4..3591a64b0cdd 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -1,4 +1,4 @@ -import React, {PureComponent} from 'react'; +import React, {useEffect, useState} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import _ from 'underscore'; @@ -60,22 +60,23 @@ const defaultProps = { name: '', }; -class Avatar extends PureComponent { - constructor(props) { - super(props); - this.state = { - imageError: false, - }; - } +function Avatar(props) { + const [imageError, setImageError] = useState(false); - componentDidUpdate(prevProps) { - const isReconnecting = prevProps.network.isOffline && !this.props.network.isOffline; - if (!this.state.imageError || !isReconnecting) { - return; - } - this.setState({imageError: false}); + useEffect(() => { + const isReconnecting = prevProps.network.isOffline && !props.network.isOffline; + if (!imageError || !isReconnecting) { + return; + } + setImageError(false); + }, [props.network.isOffline]); + + if (!props.source) { + return null; } +} + render() { if (!this.props.source) { return null; From c6af9271037a008705c55aecb828e7d14c3f82b5 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Mon, 10 Apr 2023 12:29:02 +0530 Subject: [PATCH 2/3] fixed a typo and migrated rest of the code --- src/components/Avatar.js | 115 +++++++++++++++++++-------------------- src/styles/StyleUtils.js | 4 +- 2 files changed, 58 insertions(+), 61 deletions(-) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 3591a64b0cdd..49fe4e3653e8 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -1,4 +1,4 @@ -import React, {useEffect, useState} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import _ from 'underscore'; @@ -62,70 +62,67 @@ const defaultProps = { function Avatar(props) { const [imageError, setImageError] = useState(false); + const prevNetworkStatusRef = useRef(props.network.isOffline); - useEffect(() => { - const isReconnecting = prevProps.network.isOffline && !props.network.isOffline; - if (!imageError || !isReconnecting) { - return; - } - setImageError(false); + useEffect(() => { + const isReconnecting = prevNetworkStatusRef.current && !props.network.isOffline; + if (!imageError || !isReconnecting) { + return; + } + setImageError(false); }, [props.network.isOffline]); - if (!props.source) { - return null; - } - -} - - render() { - if (!this.props.source) { - return null; - } + useEffect(() => { + // Used to store previous network state to compare on next render + prevNetworkStatusRef.current = 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})} /> - )} - - ); + 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 17893cb94c85..91780388c627 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]; @@ -970,7 +970,7 @@ export { getEmojiSuggestionItemStyle, getEmojiSuggestionContainerStyle, getColoredBackgroundStyle, - getDefaultWorspaceAvatarColor, + getDefaultWorkspaceAvatarColor, getAvatarBorderRadius, getEmojiReactionBubbleStyle, getEmojiReactionTextStyle, From 420c6c25db10b673e59f3d72ac58aa9b85d5c921 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Tue, 11 Apr 2023 19:24:38 +0530 Subject: [PATCH 3/3] added a comment --- src/components/Avatar.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 49fe4e3653e8..7aebb1d8fe68 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -70,6 +70,9 @@ function Avatar(props) { return; } setImageError(false); + + // 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]); useEffect(() => {